Spring -工厂高级特性

1、对象生命周期

什么是对象的⽣命周期

指的是一个对象创建、存活、消亡的一个完整的过程

那为什么要学习对象的⽣命周期?

由Spring负责对象的创建、存活、销毁,了解 ⽣命周期,有利于我们使⽤好Spring为我们创 建的对象

⽣命周期的3个阶段

  • 创建

    spring工厂根据对象作用域不同创建时机也不同

1. scope="singleton"
Spring⼯⼚创建的同时,对象的创建
注意:设置scope=singleton 这种情况下 也需要在获取对象的同时,创建对象<bean lazy-init="true"/>

2. scope="prototype"
Spring⼯⼚会在获取对象的同时,创建对象 即在ctx.getBean("")的时候
  • 初始化
Spring⼯⼚在创建完对象后,调⽤对象的初始化⽅法,完成对应的初始化操作(资源的初始化:数据库 IO ⽹络)
1. 初始化⽅法提供:程序员根据需求,提供初始化⽅法,最终完成初始化操作
2. 初始化⽅法调⽤:Spring⼯⼚进⾏调⽤
实现方式:
1. 实现InitializingBean接⼝,重写afterProperitesSet()方法
2. 自定义初始化方法public void myInit(){},并显示指定
    <bean id="product"class="xxx.Product" init-method="myInit"/>
3.细节分析:如果⼀个对象即实现InitializingBean 同时⼜提供的 普通的初始化⽅法 顺序是
   先InitializingBean,后普通初始化⽅法
  • 销毁
Spring销毁对象前,会调⽤对象的销毁⽅法,完成销毁操作(资源的释放操作io.close()connection.close();)
1. Spring什么时候销毁所创建的对象?
 ctx.close();
2. 销毁⽅法:程序员根据⾃⼰的需求,定义销毁⽅法,完成销毁操作
 调⽤:Spring⼯⼚完成调⽤
1. 实现DisposableBean接口,重写destroy()方法
2. 自定义销毁方法myDestroy(),并显示指定
   <bean id="" class="" initmethod="" destroy-method="myDestroy"/>
3. 细节分析:销毁⽅法的操作只适⽤于 scope="singleton"

2、配置文件参数化

把Spring配置⽂件中需要经常修改的字符串信息,转移到⼀个更⼩的配置⽂件中
1. Spring的配置⽂件中存在需要经常修改的字符串?存在 以数据库连接相关的参数 代表
2. 经常变化字符串,在Spring的配置⽂件中,直接修改不利于项⽬维护(修改)
3. 转移到⼀个⼩的配置⽂件(.properties)利于维护(修改)
配置⽂件参数化:利于Spring配置⽂件的维护(修改)

配置⽂件参数的开发步骤

  • 提供⼀个⼩的配置⽂件(.properities)

    名字:随便
    放置位置:随便
    jdbc.driverClassName =com.mysql.jdbc.Driver
    jdbc.url =jdbc:mysql://localhost:3306/jwww?useSSL=false
    jdbc.username = root
    jdbc.password = 123456
    
  • Spring的配置⽂件与⼩配置⽂件进⾏整合(引入)

    applicationContext.xml
    <context:property-placeholderlocation="classpath:/db.properties"/>
    
  • 在Spring配置⽂件中通过${key}获取⼩配置⽂件中 对应的值

3、自定义类型转化器

类型转换器

作⽤:Spring通过类型转换器把配置⽂件中字符串类型的数据,转换成了对象中成员变量对应类型的数据,进⽽完成了注⼊.

⾃定义类型转换器

原因:当Spring内部没有提供特定类型转换器时,⽽程序员在应⽤的过程中还需要使⽤,那么就需要程序员⾃⼰定义类型转换器.
  • 类 implements Converter接⼝

    public class MyDateConverter implements Converter<String,Date> {
     /*
     convert⽅法作⽤:String ---> DateSimpleDateFormat sdf = newSimpleDateFormat();
     sdf.parset(String) ---> Date
     param:source 代表的是配置⽂件中 ⽇期字符串 <value>2020-10-1</value>
     return : 当把转换好的Date作为convert⽅法的返回值后,Spring⾃动的为birthday属性进⾏注⼊(赋值)
     */
     @Override
     public Date convert(Stringsource) {
     Date date = null;
     try {
         SimpleDateFormat sdf = newSimpleDateFormat("yyyy-MM-dd");
         date = sdf.parse(source);
     } catch (ParseException e) {
    	e.printStackTrace();
     }
         return date;
     }
    }
    
  • 在Spring的配置⽂件中进行配置

    • MyDateConverter对象创建出来

      <bean id="myDateConverter" class="xxxx.MyDateConverter"/>
      
    • 类型转化器注册(告诉spring是一个类型转换器)

      ⽬的:告知Spring框架,我们所创建的MyDateConverter是⼀个类型转换器
      <!--⽤于注册类型转换器-->
      <bean id="conversionService"class="org.springframework.context.support.ConversionServiceFactoryBean">
           <property name="converters">
               <set>
                   <ref bean="myDateConverter"/>
               </set>
           </property>
      </bean>
      

细节

  • MyDateConverter中的⽇期的格式,通过依赖注⼊ 的⽅式,由配置⽂件完成赋值。

    public class MyDateConverter implements Converter<String,Date> {
     /*
     convert⽅法作⽤:String ---> DateSimpleDateFormat sdf = newSimpleDateFormat();
     sdf.parset(String) ---> Date
     param:source 代表的是配置⽂件中 ⽇期字符串 <value>2020-10-1</value>
     return : 当把转换好的Date作为convert⽅法的返回值后,Spring⾃动的为birthday属性进⾏注⼊(赋值)
     */
     //提取日期格式字符串
     private String pattern;
     //提供set、get方法供spring属性注入   
     public String getPattern() {
         return pattern;
     }
     public voidsetPattern(String pattern) {
         this.pattern = pattern;
     }   
        
        
        
        
     @Override
     public Date convert(Stringsource) {
     Date date = null;
     try {
         SimpleDateFormat sdf = newSimpleDateFormat(pattern); //抽取
         date = sdf.parse(source);
     } catch (ParseException e) {
    	e.printStackTrace();
     }
         return date;
     }
    }
    

    拿到配置文件配置

    <!--Spring创建MyDateConverter类型对象-->
    <bean id="myDateConverter"class="com.baizhiedu.converter.MyDateConverter">
         <property name="pattern" value="yyyy-MM-dd"/>
    </bean>
    
    • ConversionSeviceFactoryBean 定义 id属性 值必须 conversionService

    • Spring框架内置⽇期类型的转换器(不符合国人阅读习惯)

      ⽇期格式:2020/05/01 (不⽀持 :2020-05-01)
      

4、后置处理Bean

BeanPostProcessor作⽤:对Spring⼯⼚所创建的对象,进⾏再加⼯。
底层实现:AOP
注意:BeanPostProcessor接⼝
         xxxx(){
      }

后置处理Bean的运⾏原理分析

程序员实现BeanPostProcessor规定接⼝中的⽅法:
Object postProcessBeforeInitiallization(Object bean String beanName)
作⽤:Spring创建完对象,并进⾏注⼊后,可以运⾏Before⽅法进⾏加⼯获得Spring创建好的对象 :通过⽅法的参数最终通过返回值交给Spring框架

Object postProcessAfterInitiallization(Object bean String beanName)
作⽤:Spring执⾏完对象的初始化操作后,可以运⾏After⽅法进⾏加⼯获得Spring创建好的对象 :通过⽅法的参数最终通过返回值交给Spring框架

实战中:
BeanPostProcessor的开发步骤
1. 类 实现 BeanPostProcessor接⼝很少处理Spring的初始化操作:没有必要区分Before After。只需要实现其中的⼀个After⽅法即可
注意:
postProcessBeforeInitiallization
 return bean对象
  • BeanPostProcessor的开发步骤

    1. 类 实现 BeanPostProcessor接⼝

      public class MyBeanPostProcessor implements BeanPostProcessor
      {
           @Override
           public Object postProcessBeforeInitialization(Object bean, StringbeanName) throws
          BeansException {
               return bean;
           }
          @Override
           public Object postProcessAfterInitialization(Object bean, String beanName) throws
          BeansException {
               Categroy categroy =(Categroy) bean;
               categroy.setName("xiaowb");
               return categroy;
           }
      }
      
    2. Spring的配置⽂件中进⾏配置

      <bean id="myBeanPostProcessor" class="xxx.MyBeanPostProcessor"/>
      
    3. BeanPostProcessor细节

      BeanPostProcessor会对Spring⼯⼚中所有创建的对象进⾏加⼯。
      
posted @ 2021-10-01 16:37  jewww  阅读(86)  评论(0)    收藏  举报