1. Bean生命周期

1.1. Bean生命周期

BeanFactory接口的注释上, 有这么一段话:一个BeanFactory的实现应尽可能地支持标准的bean生命周期接口。并描述了bean生命周期的全套初始化方法及顺序:

Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:

1. BeanNameAware's setBeanName
2. BeanClassLoaderAware's setBeanClassLoader
3. BeanFactoryAware's setBeanFactory
4. EnvironmentAware's setEnvironment
5. EmbeddedValueResolverAware's setEmbeddedValueResolver
6. ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
7. ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
8. MessageSourceAware's setMessageSource (only applicable when running in an application context)
9. ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
10. ServletContextAware's setServletContext (only applicable when running in a web application context)
11. postProcessBeforeInitialization methods of BeanPostProcessors
12. InitializingBean's afterPropertiesSet
13. a custom init-method definition
14. postProcessAfterInitialization methods of BeanPostProcessors

On shutdown of a bean factory, the following lifecycle methods apply:

1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
2. DisposableBean's destroy
3. a custom destroy-method definition

Spring中bean从创建到销毁,整个生命周期一共有几个阶段:

  1. 实例化bean
  2. 设置对象属性
  3. 检查Aware相关接口并设置相关依赖,包括下面Aware接口:
    1. BeanNameAware's setBeanName
    2. BeanClassLoaderAware's setBeanClassLoader
    3. BeanFactoryAware's setBeanFactory
    4. EnvironmentAware's setEnvironment
    5. EmbeddedValueResolverAware's setEmbeddedValueResolver
    6. ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
    7. ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
    8. MessageSourceAware's setMessageSource (only applicable when running in an application context)
    9. ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
    10. ServletContextAware's setServletContext (only applicable when running in a web application context)
  4. BeanPostProcessor前置处理
  5. 检查是否是InitializaingBean以决定是否调用afterPropertiesSet方法
  6. 检查是否配置有自定义的init-method方法
  7. BeanPostProcessor后置处理
  8. 注册必要的Destruction相关回调接口

在销毁之前,生命周期接口方法如下:

  1. 是否实现DisposableBean接口
  2. 是否配置有自定义的destroy方法;

1.2. 生命周期Demo

1.2.1. xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="postProcessorBean" class="samples.spring.PostProcessorBean"/>

    <!--<context:component-scan base-package="samples.spring"/>-->

    <bean id="lifeCycleBean" class="samples.spring.LifeCycleBean" init-method="initMehotd">
    </bean>
</beans>

1.2.2. PostProcessorBean

/**
 * BeanPostProcessor 接口会应用于所有Bean实例化时进行回调, 与InitializingBean不同
 *
 * @author wangyuchuan
 * @date 2018/1/9
 * @see BeanPostProcessor
 * @see org.springframework.beans.factory.InitializingBean
 */
public class PostProcessorBean implements BeanPostProcessor {
    public static final Logger log = LoggerFactory.getLogger(PostProcessorBean.class);

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        log.info("Spring回调BeanPostProcessor's postProcessBeforeInitialization method invoked: {}", beanName);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        log.info("Spring回调BeanPostProcessor's postProcessAfterInitialization method invoked: {}", beanName);
        return bean;
    }
}

1.2.3. LifeCycleBean

/**
 * Bean生命周期方法
 * @author wangyuchuan
 * @date 2018/1/9
 */
public class LifeCycleBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware,
    ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, InitializingBean {
    public static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class);

    public LifeCycleBean() {
        log.info("构造函数被调用...");
    }

    @Override
    public void setBeanName(String name) {
        log.info("Spring回调BeanNameAware's setBeanName invoked: {}", name);
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        log.info("Spring回调BeanClassLoaderAware's setBeanClassLoader method invoked: {}", classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        log.info("Spring回调BeanFactoryAware's setBeanFactory method invoked: {}", beanFactory);
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        log.info("Spring回调ResourceLoaderAware's setResourceLoader method invoked: {}", resourceLoader);
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        log.info("Spring回调ApplicationEventPublisherAware's setApplicationEventPublisher method invoked: {}", applicationEventPublisher);
    }

    @Override
    public void setMessageSource(MessageSource messageSource) {
        log.info("Spring回调MessageSourceAware's setMessageSource method invoked: {}", messageSource);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        log.info("Spring回调ApplicationContextAware's setApplicationContext method invoked: {}", applicationContext);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("Spring回调InitializingBean's afterPropertiesSet method invoked:");
    }

    @Override
    public void setEnvironment(Environment environment) {
        log.info("Spring回调EnvironmentAware's setEnvironment method invoked: {}", environment);
    }

    public void initMehotd() {
        log.info("Spring回调initMehotd method invoked:");
    }
}

1.2.4. 输出日志

15:35:12.389 [main] INFO samples.spring.LifeCycleBean - 构造函数被调用...
15:35:12.389 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'lifeCycleBean' to allow for resolving potential circular references
15:35:12.389 [main] INFO samples.spring.LifeCycleBean - Spring回调BeanNameAware's setBeanName invoked: lifeCycleBean
15:35:12.391 [main] INFO samples.spring.LifeCycleBean - Spring回调BeanClassLoaderAware's setBeanClassLoader method invoked: sun.misc.Launcher$AppClassLoader@18b4aac2
15:35:12.391 [main] INFO samples.spring.LifeCycleBean - Spring回调BeanFactoryAware's setBeanFactory method invoked: org.springframework.beans.factory.support.DefaultListableBeanFactory@223191a6: defining beans [postProcessorBean,lifeCycleBean]; root of factory hierarchy
15:35:13.310 [main] INFO samples.spring.LifeCycleBean - Spring回调EnvironmentAware's setEnvironment method invoked: StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[systemProperties,systemEnvironment]}
15:35:13.310 [main] INFO samples.spring.LifeCycleBean - Spring回调ResourceLoaderAware's setResourceLoader method invoked: org.springframework.context.support.ClassPathXmlApplicationContext@5a8e6209: startup date [Tue Jan 09 15:35:06 CST 2018]; root of context hierarchy
15:35:13.311 [main] INFO samples.spring.LifeCycleBean - Spring回调ApplicationEventPublisherAware's setApplicationEventPublisher method invoked: org.springframework.context.support.ClassPathXmlApplicationContext@5a8e6209: startup date [Tue Jan 09 15:35:06 CST 2018]; root of context hierarchy
15:35:13.311 [main] INFO samples.spring.LifeCycleBean - Spring回调MessageSourceAware's setMessageSource method invoked: org.springframework.context.support.ClassPathXmlApplicationContext@5a8e6209: startup date [Tue Jan 09 15:35:06 CST 2018]; root of context hierarchy
15:35:13.311 [main] INFO samples.spring.LifeCycleBean - Spring回调ApplicationContextAware's setApplicationContext method invoked: org.springframework.context.support.ClassPathXmlApplicationContext@5a8e6209: startup date [Tue Jan 09 15:35:06 CST 2018]; root of context hierarchy
15:35:14.006 [main] INFO samples.spring.PostProcessorBean - Spring回调BeanPostProcessor's postProcessBeforeInitialization method invoked: lifeCycleBean
15:35:14.185 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'lifeCycleBean'
15:35:14.185 [main] INFO samples.spring.LifeCycleBean - Spring回调InitializingBean's afterPropertiesSet method invoked:
15:35:14.185 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking init method  'initMehotd' on bean with name 'lifeCycleBean'
15:35:14.185 [main] INFO samples.spring.LifeCycleBean - Spring回调initMehotd method invoked:
15:35:14.185 [main] INFO samples.spring.PostProcessorBean - Spring回调BeanPostProcessor's postProcessAfterInitialization method invoked: lifeCycleBean

2. 提出问题

了解了上面的bean的生命周期之后,有一些疑惑需要先提出来:

  1. 生命周期的前10个调用方法,都是以Aware结尾的接口方法,各个XXXAware接口作用是什么?对开发者来说有没有用?
  2. 上面所有接口按照作用方式的不同如何分类?
  3. 开发者常见的涉及到Bean生命周期的操作方式有哪些?即知道了bean的生命周期,对我们有什么用?如何用?
Copyright © wychuan.com 2017 all right reserved,powered by Gitbook该文件修订时间: 2018-01-09 08:05:07

results matching ""

    No results matching ""