zoukankan      html  css  js  c++  java
  • Spring Bean的生命周期

    Spring框架中,一旦把一个Bean纳入Spring IOC容器之中,这个Bean的生命周期就会交由容器进行管理,一般担当管理角色的是BeanFactory或者ApplicationContext,认识一下Bean的生命周期活动,对更好的利用它有很大的帮助:

    下面以BeanFactory为例,说明一个Bean的生命周期活动

    • Bean的建立, 由BeanFactory读取Bean定义文件,并生成各个实例
    • Setter注入,执行Bean的属性依赖注入
    • BeanNameAware的setBeanName(), 如果实现该接口,则执行其setBeanName方法
    • BeanFactoryAware的setBeanFactory(),如果实现该接口,则执行其setBeanFactory方法
    • BeanPostProcessor的processBeforeInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processBeforeInitialization()方法
    • InitializingBean的afterPropertiesSet(),如果实现了该接口,则执行其afterPropertiesSet()方法
    • Bean定义文件中定义init-method
    • BeanPostProcessors的processAfterInitialization(),如果有关联的processor,则在Bean初始化之前都会执行这个实例的processAfterInitialization()方法
    • DisposableBean的destroy(),在容器关闭时,如果Bean类实现了该接口,则执行它的destroy()方法
    • Bean定义文件中定义destroy-method,在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法

    如果使用ApplicationContext来维护一个Bean的生命周期,则基本上与上边的流程相同,只不过在执行BeanNameAware的setBeanName()后,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization()
    实际上,ApplicationContext除了向BeanFactory那样维护容器外,还提供了更加丰富的框架功能,如Bean的消息,事件处理机制等。

    在这里一用仓颉的一幅图说明流程: 转载自 https://www.cnblogs.com/xrq730/p/6363055.html

    以下是自己测试时打印的日志信息,可以看下加载顺序:

     1 /**
     2  * @ClassName: MySpringBean
     3  * @Description: my spring bean to test
     4  * @author: daniel.zhao
     5  * @date: 2018年10月26日 上午10:12:37
     6  */
     7 public class MySpringBean implements BeanNameAware, BeanFactoryAware, InitializingBean, ApplicationContextAware {
     8 
     9     private ApplicationContext applicationContext;
    10 
    11     private static final Logger logger = LoggerFactory.getLogger(MySpringBean.class);
    12 
    13     public MySpringBean() {
    14         logger.info("new MySpringBean......");
    15     }
    16 
    17     @Override
    18     public void setApplicationContext(ApplicationContext context) throws BeansException {
    19         logger.info("ApplicationContextAware-setApplicationContext......");
    20         this.applicationContext = context;
    21     }
    22 
    23     @Override
    24     public void afterPropertiesSet() throws Exception {
    25         logger.info("InitializingBean-afterPropertiesSet......");
    26     }
    27 
    28     @Override
    29     public void setBeanFactory(BeanFactory bf) throws BeansException {
    30         logger.info("BeanFactoryAware-setBeanFactory......");
    31     }
    32 
    33     @Override
    34     public void setBeanName(String name) {
    35         logger.info("BeanNameAware-setBeanName......");
    36     }
    37 
    38     public void init() {
    39         logger.info("init-method......");
    40     }
    41 }
    /**
     * @ClassName: MySpringBeanPostProcessor
     * @author: daniel.zhao
     * @date: 2018年10月26日 上午10:40:21
     */
    @Component
    public class MySpringBeanPostProcessor implements BeanPostProcessor {
    
        private static final Logger logger = LoggerFactory.getLogger(MySpringBeanPostProcessor.class);
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof MySpringBean) {
                logger.info("BeanPostProcessor-postProcessAfterInitialization......");
            }
            return bean;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (bean instanceof MySpringBean) {
                logger.info("BeanPostProcessor-postProcessBeforeInitialization......");
            }
            return bean;
        }
    
    }
    2018-10-26 10:49:48.768  INFO 5732 --- [           main] com.daniel.bean.MySpringBean             : BeanNameAware-setBeanName......
    2018-10-26 10:49:48.769  INFO 5732 --- [           main] com.daniel.bean.MySpringBean             : BeanFactoryAware-setBeanFactory......
    2018-10-26 10:49:48.769  INFO 5732 --- [           main] com.daniel.bean.MySpringBean             : ApplicationContextAware-setApplicationContext......
    2018-10-26 10:49:48.770  INFO 5732 --- [           main] c.daniel.bean.MySpringBeanPostProcessor  : BeanPostProcessor-postProcessBeforeInitialization......
    2018-10-26 10:49:48.770  INFO 5732 --- [           main] com.daniel.bean.MySpringBean             : InitializingBean-afterPropertiesSet......
    2018-10-26 10:49:48.770  INFO 5732 --- [           main] com.daniel.bean.MySpringBean             : init-method......
    2018-10-26 10:49:48.771  INFO 5732 --- [           main] c.daniel.bean.MySpringBeanPostProcessor  : BeanPostProcessor-postProcessAfterInitialization......
  • 相关阅读:
    Go学习(5):集合
    Go学习(4):数组和切片
    Go学习(3):分支循环
    Go学习(2):基本语法
    Go学习(1):简介和配置
    input输入框只能输入数字而且开头不能为零
    JS 显示周 几和 月 日
    IntelliJ Idea 跳出括号并且光标移到末尾的快捷键
    不可小视的String字符串
    PrintWriter中的write与println方法居然就是这些区别
  • 原文地址:https://www.cnblogs.com/redcool/p/6397398.html
Copyright © 2011-2022 走看看