第十章、对象的生命周期

image-20200418155427918.png

1. 什么是对象的生命周期
  1. 指的是一个对象创建、存活、消亡的一个完整过程

2. 为什么要学习对象的生命周期
  1. Spring 负责对象的创建、存活、销毁,了解生命周期,有利于我们使用好Spring为我们创建的对象

3. 生命周期的3个阶段
  • 创建阶段

    1. Spring工厂何时创建对象
    • scope=”singleton” (默认即为”单例”) ```markdown Spring工厂创建的同时创建对象。

注意:若 scope=singleton 时也想在获取对象的同时创建对象(而不是在创建 Spring 工厂的同时创建对象) ,则:

  1. - scope="prototype"
  2. ```markdown
  3. Spring工厂会在获取对象的同时,创建对象,即 ctx.getBean("id值") 获取对象则对象创建,相当于"懒加载"。
  • 初始化阶段 ```markdown Spring 工厂在创建完对象后,调用对象的初始化方法,完成对应的初始化操作。
  1. 初始化方法提供:程序员根据需求,提供初始化方法,最终完成初始化操作
  2. 初始化方法调用:Spring 工厂进行调用 ```

    • 方法1:InitializingBean 接口

      (1)实体类实现 InitializingBean 接口; (2)重写 afterProperitesSet 方法

  1. 1.实体类实现 InitializingBean 接口
  2. eg. public class User implements InitializingBean { ... }
  3. 2.重写 afterPropertiesSet 方法。
  4. //程序员根据需求,实现的方法,完成初始化操作
  5. public void afterProperitesSet(){
  6. //TODO:需要实现的初始化操作
  7. }
  • 方法2:对象中提供一个普通的方法

    (1)实体类中自定义一个方法(eg. public void myInit() { … } ); (2)bean 中新增 init-method 标签进行引用。

  1. // 自定义初始化方法(名称随意)
  2. public void myInit(){
  3. //TODO:初始化操作
  4. }
  5. # init-method 标签进行引用
  6. <bean id="product" class="xxx.Product" init-method="myInit"/>
  • 细节分析

    1. 如果一个对象既实现 InitializingBean 接口同时又提供普通的初始化方法,则调用顺序为:

      1. 1. InitializingBean 中的afterProperitesSet 方法
      2. 2. 自定义的普通初始化方法(eg. myInit
    2. 注入一定发生在初始化操作的前面

    3. 什么叫做初始化操作
      1. 应用场景:
      2. 资源的初始化,如数据库、IO 网络 .....
  • 销毁阶段 ```markdown Spring 销毁对象前,会调用对象的销毁方法,完成销毁操作
  1. Spring 什么时候销毁所创建的对象? ctx.close();
  2. 销毁方法:程序员根据自己的需求,定义销毁方法,完成销毁操作 调用:Spring 工厂完成调用

    1. - 实现 DisposableBean 接口
    2. ```java
    3. // 实现 DisposableBean 接口
    4. public class User implements DisposableBean{
    5. public void destroy()throws Exception{
    6. }
    7. ...
    8. }
    • 实体类中定义一个普通的销毁方法 ```java // 实体类中自定义一个销毁方法(名称随意) public void myDestroy()throws Exception{

}

  1. - 细节分析
  2. 1. 销毁方法的操作只适用于 scope="singleton"
  3. 1. 什么叫做销毁操作
  4. ```markdown
  5. 主要指的就是 资源的释放操作 io.close() connection.close();

第十一章、配置文件参数化

  1. Spring 配置文件中需要经常修改的字符串信息,转移到一个更小的配置文件中
  2. 1. Spring 的配置文件中存在需要经常修改的字符串?
  3. 存在 以数据库连接相关的参数 代表
  4. 2. 经常变化字符串,在 Spring 的配置文件中,直接修改
  5. 不利于项目维护(修改)
  6. 3. 转移到一个小的配置文件(.properties)
  7. 利于维护(修改)
  8. 配置文件参数化:利于Spring配置文件的维护(修改)

1. 配置文件参数的开发步骤
  • 提供一个小的配置文件(.properities)

    名字:随便,eg. db.properties 放置位置:随便,eg. resouce 文件夹下

db.properties

  1. jdbc.driverClassName = com.mysql.jdbc.Driver
  2. jdbc.url = jdbc:mysql://localhost:3306/suns?useSSL=false
  3. jdbc.username = root
  4. jdbc.password = 123456
  • 实体类 ConnectionBean

    1. public class ConnectionBean{
    2. private String driverClassName;
    3. private String url;
    4. private String username;
    5. private String password;
    6. ...
    7. }
  • Spring 的配置文件 applicationContext 与小配置文件 db.properties 进行整合 ```xml applicationContext.xml

<?xml version=”1.0” encoding=”UTF-8”?>

  1. - Spring配置文件中通过${key}获取小配置文件中对应的值<br />
  2. ![image-20200418171133796.png](https://cdn.nlark.com/yuque/0/2020/png/419703/1602153362201-2d68ebab-3577-42c2-97b2-8b86834459ec.png#align=left&display=inline&height=619&margin=%5Bobject%20Object%5D&name=image-20200418171133796.png&originHeight=619&originWidth=1966&size=230624&status=done&style=none&width=1966)
  3. <a name="30b0e3e6"></a>
  4. #### 第十二章、自定义类型转换器
  5. <a name="3599967f"></a>
  6. ##### 1. 类型转换器
  7. ```markdown
  8. 作用:Spring 通过类型转换器把配置文件中字符串类型的数据,转换成了对象中成员变量对应类型的数据,进而完成了注入

image-20200418201732220.png

2. 自定义类型转换器
  1. 原因:当Spring内部没有提供特定类型转换器时,而程序员在应用的过程中还需要使用,那么就需要程序员自己定义类型转换器
  • 继承 Converter 接口并重写 convert 方法
  1. public class MyDateConverter implements Converter<String, Date> {
  2. /*
  3. convert方法作用:String ---> Date
  4. SimpleDateFormat sdf = new SimpleDateFormat();
  5. sdf.parset(String) ---> Date
  6. param:source 代表的是配置文件中 日期字符串 <value>2020-10-11</value>
  7. return : 当把转换好的Date作为convert方法的返回值后,Spring自动的为birthday属性进行注入(赋值)
  8. */
  9. @Override
  10. public Date convert(String source) {
  11. Date date = null;
  12. try {
  13. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  14. date = sdf.parse(source);
  15. } catch (ParseException e) {
  16. e.printStackTrace();
  17. }
  18. return date;
  19. }
  20. }
  • 在 Spring 的配置文件中进行配置

    • MyDateConverter 对象创建出来

      1. <bean id="myDateConverter" class="xxxx.MyDateConverter"/>
    • 类型转换器的注册

      1. 目的:告知 Spring 框架,我们所创建的 MyDateConverter 是一个类型转换器
      2. <!--用于注册类型转换器,注意:id 必须是 conversionService。-->
      3. <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
      4. <property name="converters">
      5. <set>
      6. <ref bean="myDateConverter"/>
      7. </set>
      8. </property>
      9. </bean>

3. 细节
  • MyDateConverter 中的日期的格式,通过依赖注入的方式,由配置文件完成赋值。

    1. public class MyDateConverter implements Converter<String, Date> {
    2. private String pattern;
    3. public String getPattern() {
    4. return pattern;
    5. }
    6. public void setPattern(String pattern) {
    7. this.pattern = pattern;
    8. }
    9. /*
    10. convert方法作用:String ---> Date
    11. SimpleDateFormat sdf = new SimpleDateFormat();
    12. sdf.parset(String) ---> Date
    13. param:source 代表的是配置文件中 日期字符串 <value>2020-10-11</value>
    14. return : 当把转换好的Date作为convert方法的返回值后,Spring自动的为birthday属性进行注入(赋值)
    15. */
    16. @Override
    17. public Date convert(String source) {
    18. Date date = null;
    19. try {
    20. SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    21. date = sdf.parse(source);
    22. } catch (ParseException e) {
    23. e.printStackTrace();
    24. }
    25. return date;
    26. }
    27. }
    1. <!--Spring 创建 MyDateConverter 类型对象-->
    2. <bean id="myDateConverter" class="com.baizhiedu.converter.MyDateConverter">
    3. <property name="pattern" value="yyyy-MM-dd"/>
    4. </bean>
  • ConversionSeviceFactoryBean 定义 id属性 值必须 conversionService

  • Spring框架内置日期类型的转换器
    1. 日期格式:2020/05/01 (不支持"2020-05-01"这种格式)

第十三章、后置处理Bean

  1. BeanPostProcessor作用:对 Spring 工厂所创建的对象,进行再加工。
  2. AOP 底层实现:
  3. 注意:BeanPostProcessor 接口
  4. xxxx(){
  5. }
  • 后置处理Bean的运行原理分析
  • image-20200420155053027.png
  1. 程序员实现BeanPostProcessor规定接口中的方法:
  2. Object postProcessBeforeInitiallization(Object bean String beanName)
  3. 作用:Spring 创建完对象,并进行注入后,可以运行 Before 方法进行加工
  4. 获得 Spring 创建好的对象 :通过方法的参数
  5. 最终通过返回值交给Spring框架
  6. Object postProcessAfterInitiallization(Object bean String beanName)
  7. 作用:Spring执行完对象的初始化操作后,可以运行After方法进行加工
  8. 获得Spring创建好的对象 :通过方法的参数
  9. 最终通过返回值交给Spring框架
  10. 实战中:
  11. 很少处理Spring的初始化操作:没有必要区分Before After。只需要实现其中的一个After方法即可
  12. 注意:
  13. postProcessBeforeInitiallization
  14. return bean对象
  • BeanPostProcessor的开发步骤

    1. 类 实现 BeanPostProcessor接口 ```java public class MyBeanPostProcessor implements BeanPostProcessor {

      @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; }

      @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

      Categroy categroy = (Categroy) bean; categroy.setName(“xiaowb”);

  1. return categroy;
  2. }

}

  1. 1. Spring的配置文件中进行配置
  2. ```xml
  3. <bean id="myBeanPostProcessor" class="xxx.MyBeanPostProcessor"/>
  1. BeanPostProcessor细节
    1. BeanPostProcessor会对Spring工厂中所有创建的对象进行加工。