spring基本使用(6)-ApplicationContext中bean的生命周期

1、借用一张ApplicationContext中bean的生命周期流程图:

 

2、ApplicationContext bean生命周期涉及组件说明:

     在BeanFactory的bean生命周期中的组件在ApplicationContext中的bean生命周期中也都存在,除此之外ApplicationContext bean生命周期涉及组件还多出了几个,我们主要介绍多出来的几个组件。

       2.1、BeanFactoryPostProcessor:bean工厂后置处理器。

              主要职责:就是在ApplicationContext的beanFactory 这个bean 实例准备就绪后,就会调用所有实现了BeanFactoryPostProcessor接口的类的 postProcessBeanFactory()方法,在这里我们可以随意修改一些bean的BeanDefinition,这就是“偷天换日”,每个实现类的postProcessBeanFactory()方法在整个ApplicationContext加载中只会执行一次(区分BeanPostProcessor)。

 

       2.2、ApplicationContextAware:应用上下文感知器。

               主要职责:给需要知道自己所处ApplicationContext 的bean 调用setApplicationContext()方法。

 

       2.3、@PostConstruct:定义初始化bean之前操作的注解。

                主要职责:定义bean初始化之前需要做的操作,标注在方法上面表示bean初始化之前调用此方法。

     

        2.4、@PreDestroy:定义注销bean之前操作的注解。

               主要职责:定义bean销毁之前需要做的操作,标注在方法上面表示bean销毁之前调用此方法。

 

3、ApplicationContext中bean生命周期流程: 

      1、调用所有实现了BeanFactoryPostProcessor接口的类的 postProcessBeanFactory()方法。
      2、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法。
      3、实例化bean。
      4、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()方法。
      5、调用添加的所有InstantiationAwareBeanPostProcessor.postProcessPropertyValues()方法。
      6、如果bean实现了BeanNameAware接口,调用bean的setBeanName()函数。
      7、如果bean实现了BeanFactoryAware接口,调用bean的setBeanFactory()函数。
      8、如果bean实现看ApplicationContextAware接口,调用bean的setApplicationContext()方法。
      9、调用添加的所有BeanPostProcessor.postProcessBeforeInitialization()方法。
    10、调用bean中 @PostConstruct注解函数的处理。
    11、如果bean实现了InitializingBean接口,调用bean的afterPropertiesSet()方法。
    12、如果<bean/>上定义的init-method 属性,则调用bean中的init-method属性值的方法。
    13、调用添加的所有BeanPostProcessor.postProcessAfterInitialization()方法。

 销毁bean触发如下:
    14、调用bean中 @PreDestroy注解函数的处理。
    15、如果bean实现了DisposableBean接口,则调用bean中的destroy()方法。
    16、如果<bean/>上定义的destroy-method 属性,则调用bean中的destroy-method属性值的方法。

 

4、ApplicationContextbean生命周期流程测试 :

    测试代码:
         ApplicationContext ac = new ClassPathXmlApplicationContext("spring-context.xml");
         Bar bar = (Bar) ac.getBean("bar");
         ((ClassPathXmlApplicationContext) ac).destroy();
    测试结果:
         BeanFactoryPostProcessor.postProcessBeanFactory。。。                              整个上下文只会触发一次
         InstantiationAwareBeanPostProcessor 的 before。。。                                   每个bean生命周期中都会触发一次 
         Construct...                                                                                                        每个bean生命周期中都会触发一次 
         InstantiationAwareBeanPostProcessor 的 after。。。                                      每个bean生命周期中都会触发一次 
         InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues。。。 每个bean生命期中都会触发一次 
         BeanPostProcessor 的 before。。。                                                                 每个bean生命周期中都会触发一次        
         @PostConstruct注解。。。                                                                               bean如果配置了则生命周期中都会触发一次
         InitializingBean 的afterPropertiesSet。。。                                                      bean如果配置了则生命周期中都会触发一次
         <bean/> init-method 属性。。。                                                                     bean如果配置了则生命周期中都会触发一次
         BeanPostProcessor 的 after。。。                                                                    每个bean生命周期中都会触发一次 

         @PreDestroy注解。。。                                                                                    bean如果配置了则生命周期中都会触发一次
         DisposableBean 的 destroy。。。                                                                     bean如果配置了则生命周期中都会触发一次
         <bean/> destroy-method 属性。。。                                                              bean如果配置了则生命周期中都会触发一次

 

5、BeanFactory与 ApplicationContext生命周期的区别

         1、BeanFactory 生命周期中InstantiationAwareBeanPostProcessor、BeanPostProcessor等处理器需要手动调用BeanFactory.addBeanPostProcessor()方法将其注册到BeanFactory中,而ApplicationContext中的BeanFactoryPostProcessor、InstantiationAwareBeanPostProcessor、BeanPostProcessor等后置处理器只需要定义BeanDefinition, ApplicationContext会根据反射自动将其注册到ApplicationContext的BeanFactory中。


          2、BeanFactory 中只有在调用BeanFactory.getBean()方法才会开始bena的生命周期,这就是所谓的spring “第一次惩罚”的问题,而ApplicationContext 在加载的过程中就会将开始bean的生命周期,底层也是使用ApplicationContext 的BeanFactory.getBean()函数来将除了延迟加载的所有bena的生命周期走完,解决了“第一次惩罚”的问题,也解决了在加载的时候就将bean配置如果存在的错误,提前暴露出来。


          3、ApplicationContext 中bean的生命周期多了4个组件,一是BeanFactoryPostProcessor,其实从理论上来说BeanFactoryPostProcessor这个应该是BeanFactory 工厂实例的生命周期组件。二是ApplicationContextAware 接口。三是@PostConstruct 注解。四是@PreDestroy注解。

 

6、案例中使用的代码:

public class Bar implements InitializingBean,DisposableBean {
    private String price;
    public Bar() {
        System.out.println("Construct...");
    }
    public String getPrice() {return price;}

    public void setPrice(String price) {this.price = price;}

    @PostConstruct
    public void intit(){
        System.out.println("@PostConstruct注解。。。");
    }
    @PreDestroy
    public void preDestroy(){
        System.out.println("@PreDestroy注解。。。");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("DisposableBean 的 destroy。。。");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean 的afterPropertiesSet。。。");
    }

    public void myinit(){
        System.out.println("<bean/> init-method 属性。。。");
    }
    public void mydestroy(){
        System.out.println("<bean/> destroy-method 属性。。。");
    }
}


自定义BeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory configurableListableBeanFactory)
                                                   throws BeansException {
        System.out.println("BeanFactoryPostProcessor.postProcessBeanFactory。。。" +
                "整个bean工厂 只执行一次。。。BeanFactoryPostProcessor");
        BeanDefinition bar = configurableListableBeanFactory.getBeanDefinition("bar");
        bar.getPropertyValues().add("price", "234");
    }
}


自定义InstantiationAwareBeanPostProcessor
@Component
public class MyInstantiationAwareBeanPostProcessor extends 
        InstantiationAwareBeanPostProcessorAdapter {

    @Override
    public Object postProcessBeforeInstantiation(Class <?> aClass,
                                                 String s) throws BeansException {
        if (s.equals("bar")){
            System.out.println("InstantiationAwareBeanPostProcessor 的 before。。。");
        }
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object o, 
                                         String s) 
                                         throws BeansException {
        if (s.equals("bar")){
            System.out.println("InstantiationAwareBeanPostProcessor 的 after。。。");
        }
        return true;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues propertyValues,
                                                    PropertyDescriptor[]
                                                    propertyDescriptors,
                                                    Object o, 
                                                    String s) throws BeansException {
        if (s.equals("bar")){
            System.out.println("InstantiationAwareBeanPostProcessor 的 
                                                    postProcessPropertyValues。。。");
        }
        return propertyValues;
    }
}


自定义BeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object o,
                                                  String s) 
                                                  throws BeansException {
        if (s.equals("bar")){
            System.out.println("BeanPostProcessor 的 before。。。");
        }
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, 
                                                 String s) 
                                                 throws BeansException {
        if (s.equals("bar")){
            System.out.println("BeanPostProcessor 的 after。。。");
        }
        return o;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值