• Spring Bean 生命周期


    说到Spring Bean的生命周期,有好多内容,大部分都用不到,除了几个关键点可以用到。以下图就描述了

     

    上面的图就看看吧,我也不讲诉太多,就列举几个常见的,普通的流程吧。

    在大部分情况下我们基本用的是适配器设计模式,就是一个class里面 调用其他其他class,并以属性形式注入存在。主要关注下初始化和销毁阶段的内容,

    然后实现InitializingBean, DisposableBean,再然后写Bean 中的init-method和destroy-method,了解下其流程

    我列举了一个Car,里面有个RedCar属性,来获取其名称。都是注解版

     1 public class Car implements InitializingBean, DisposableBean
     2 {
     3     private String name;
     4     private RedCar redCar;
     5 
     6     public Car()
     7     {
     8         System.out.println("Car构造函数");
     9     }
    10 
    11     public String getName()
    12     {
    13         return name;
    14     }
    15 
    16     @Value("China Car")
    17     public void setName(String name)
    18     {
    19         System.out.println("Car设置属性");
    20         this.name = name;
    21     }
    22 
    23     public RedCar getRedCar()
    24     {
    25         return redCar;
    26     }
    27     
    28     @Autowired
    29     public void setRedCar(RedCar redCar)
    30     {
    31         System.out.println("Car内的RedCar设置属性");
    32         this.redCar = redCar;
    33     }
    34 
    35     public void myInit()
    36     {
    37         System.out.println("Car调用<bean>的init-method属性指定的初始化方法");
    38     }
    39 
    40     @Override
    41     public void afterPropertiesSet() throws Exception
    42     {
    43         System.out.println("Car调用InitializingBean的afterPropertiesSet");
    44     }
    45 
    46     @Override
    47     public void destroy() throws Exception
    48     {
    49         System.out.println("Car调用DisposableBean的destroy");
    50     }
    51 
    52     public void myDestroy()
    53     {
    54         System.out.println("Car调用<bean>的destroy-method属性指定的初始化方法");
    55     }
    56 }

    RedCar:

     1 public class RedCar implements InitializingBean, DisposableBean
     2 {
     3     private String name;
     4 
     5     public RedCar()
     6     {
     7         System.out.println("RedCar构造函数");
     8     }
     9 
    10     public String getName()
    11     {
    12         return name;
    13     }
    14 
    15     @Value("China RedCar")
    16     public void setName(String name)
    17     {
    18         System.out.println("RedCar设置属性");
    19         this.name = name;
    20     }
    21 
    22     @Override
    23     public void afterPropertiesSet() throws Exception
    24     {
    25         System.out.println("RedCar调用InitializingBean的afterPropertiesSet");
    26     }
    27 
    28     @Override
    29     public void destroy() throws Exception
    30     {
    31         System.out.println("RedCar调用DisposableBean的destroy");
    32     }
    33 
    34     public void myInit()
    35     {
    36         System.out.println("RedCar调用<bean>的init-method属性指定的初始化方法");
    37     }
    38 
    39     public void myDestroy()
    40     {
    41         System.out.println("RedCar调用<bean>的destroy-method属性指定的初始化方法");
    42     }
    43 }

    其中@Autowired注解放在setxxx方法上,不要放在成员变量上,不然是不会执行setxxx的内容

    然后写个Configuration注解注入Bean,并写上initMethod和destroyMethod方法

     1 @Configuration
     2 public class MyConfig
     3 {
     4     @Bean(initMethod = "myInit", destroyMethod = "myDestroy")
     5     public Car getCar()
     6     {
     7         return new Car();
     8     }
     9 
    10     @Bean(initMethod = "myInit", destroyMethod = "myDestroy")
    11     public RedCar getRedCar()
    12     {
    13         return new RedCar();
    14     }
    15 }

    Main函数执行

     1 public class Application
     2 {
     3     public static void main(String[] args)
     4     {
     5         AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
     6         String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
     7         
     8         Car car = annotationConfigApplicationContext.getBean(Car.class);
     9         annotationConfigApplicationContext.close();
    10     }
    11 }

    其中annotationConfigApplicationContext.close()是用来销毁Bean

    运行结果如下

    Car构造函数
    Car设置属性
    RedCar构造函数
    RedCar设置属性
    RedCar调用InitializingBean的afterPropertiesSet
    RedCar调用<bean>的init-method属性指定的初始化方法
    Car内的RedCar设置属性
    Car调用InitializingBean的afterPropertiesSet
    Car调用<bean>的init-method属性指定的初始化方法
    Car调用DisposableBean的destroy
    Car调用<bean>的destroy-method属性指定的初始化方法
    RedCar调用DisposableBean的destroy
    RedCar调用<bean>的destroy-method属性指定的初始化方法

    总结:

    1、先调用自己的无参数构造函数(你写个有参构造是没啥作用的)

    2、再执行属性注入,就先调用属性类的构造函数

    3、再注入属性类的属性

    4、调用属性类的InitializingBean的afterPropertiesSet

    5、调用属性类的init-method

    6、再返回该类的属性setxxx

    7、.....重复步骤

    8、销毁的顺序要注意下,最后执行的属性类的销毁

    然后Spring 又出现了一个后期处理加强的Bean处理 BeanPostProcessor 接口

    这个BeanPostProcessor是针对所有的bean

    代码如下:

     1 @Component
     2 public class MyPostProcessor implements BeanPostProcessor
     3 {
     4     @Override
     5     public Object postProcessBeforeInitialization(Object o, String s) throws BeansException
     6     {
     7         System.out.println(String.format("BeanPostProcessor-postProcessBeforeInitialization:%s,%s", o, s));
     8         return o;
     9     }
    10 
    11     @Override
    12     public Object postProcessAfterInitialization(Object o, String s) throws BeansException
    13     {
    14         System.out.println(String.format("BeanPostProcessor-postProcessAfterInitialization:%s,%s", o, s));
    15         return o;
    16     }
    17 }

    运行如下:

    Car构造函数
    Car设置属性
    RedCar构造函数
    RedCar设置属性
    BeanPostProcessor-postProcessBeforeInitialization:dto.RedCar@70b0b186,getRedCar
    RedCar调用InitializingBean的afterPropertiesSet
    RedCar调用<bean>的init-method属性指定的初始化方法
    BeanPostProcessor-postProcessAfterInitialization:dto.RedCar@70b0b186,getRedCar
    Car内的RedCar设置属性
    BeanPostProcessor-postProcessBeforeInitialization:dto.Car@ba8d91c,getCar
    Car调用InitializingBean的afterPropertiesSet
    Car调用<bean>的init-method属性指定的初始化方法
    BeanPostProcessor-postProcessAfterInitialization:dto.Car@ba8d91c,getCar
    Car调用DisposableBean的destroy
    Car调用<bean>的destroy-method属性指定的初始化方法
    RedCar调用DisposableBean的destroy
    RedCar调用<bean>的destroy-method属性指定的初始化方法

    总结:

    postProcessBeforeInitialization和postProcessAfterInitialization是在InitializingBean和init-method之前后执行的。

    postProcessBeforeInitialization是前

    postProcessAfterInitialization是后

    其他的不说了,说多了记不住,最后一句话概括,bean的生命周期先自身构造再调用依赖后再回来执行自己,销毁顺序反向,先自己销毁再销毁依赖的,BeanPostProcessor就是在初始化中前后执行。

  • 相关阅读:
    javascript如何判断一个对象是不是数组
    Socket 通讯
    XML 文件解析
    iOS 钥匙串 指纹识别 get和Post请求的区别
    MOS X 下Apache服务器配置,及日志读取
    iOS中图片动画的三种模式及基本的代码实现
    UI中 frame 与 transform的用法与总结
    Xcode 缓存 帮助文档 隐藏文件夹显示方法
    NSDate用法整理总结
    iOS沙盒机制的基本操作总结
  • 原文地址:https://www.cnblogs.com/zjtao/p/12220839.html
Copyright © 2020-2023  润新知