Spring中Bean的生命周期

最近项目有用到对Spring的扩展,顺便整理下Spring中Bean的生命周期。

BeanFactory中Bean的生命周期

在这里插入图片描述

  1. 当调用者通过getBean(beanName)向容器请求某一个bean时,如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,则在实例化Bean之前,将调用接口的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)方法。
  2. 根据配置情况调用Bean构造函数或工厂方实例化Bean。
  3. 如果容器注册了org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor接口,那么在实例化Bean后,调用该接口的postProcessAfterInstantiation(Object bean, String beanName),可在这里对已经实例化的对象做一些“梳妆打扮”。
  4. 如果Bean配置了属性信息,那么容器在这一步着手将配置设置到Bean对应的属性中,不过在设置每个属性之前将先调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)方法。
  5. 调用Bean的属性设置方法设置属性值。
  6. 如果Bean实现了org.springframework.beans.factory.BeanNameAware接口,则将调用setBeanName(String name)方法,将配置文件中该Bean对应的名称设置到Bean中。
  7. 如果Bean实现了org.springframework.beans.factory.BeanFactoryAware接口,则将调用setBeanFactory(BeanFactory beanFactory)接口方法,将BeanFactory容器实例设置到Bean中。
  8. 如果BeanFactory装配了org.springframework.beans.factory.config.BeanPostProcessor后处理器,则将调用BeanPostProcessor接口的Object postProcessBeforeInitialization(Object bean, String beanName)方法对Bean进行加工处理。其中,入参bean为当前正在处理的bean,而beanName为当前Bean的配置名,返回的对象为加工处理后的Bean。用户可以使用该方法对某些Bean进行特殊处理,甚至改变Bean的行为。BeanFactory在Spring框架中占有重要的地位,为容器提供对Bean进行后续加工处理的切入点,Spring容器所提供的各种”神奇功能“(如AOP、动态代理等)都通过BeanPostProcessor实施。
  9. 如果Bean实现org.springframework.beans.factory.InitializingBean接口,则将调用接口的afterPropertiesSet()方法。
  10. 如果在中通过init-method属性定义了初始化方法,则将执行这个方法。
  11. BeanPostProcessor后处理器定义了两个方法:其一是postProcessBeforeInitialization(),在第8步调用,其二是Object postProcessAfterInitialization(Object bean, String beanName),这个方法在此时调用,容器再次获得对Bean进行加工处理的机会。
  12. 如果在中指定Bean的作用范围为scope=“prototype”,则将bean返回给调用者,调用者负责Bean后续生命的管理,Spring不再管理这个Bean的生命周期。如果将作用范围设置为scope=“singleton”,则将Bean放入Spring IoC容器的缓存池中,并将Bean引用返回给调用者,Spring继续对这个Bean进行后续的生命管理。
  13. 对于scope=“singleton”(默认情况),当容器关闭时,将触发Spring对Bean后续生命周期的管理工作。如果Bean实现了org.springframework.beans.factory.DisposableBean接口,则将调用接口的destroy()方法,可以在此编写释放资源、记录日志等的操作。
  14. 对于scope="singleton"的Bean,如果通过的destroy-method属性指定了Bean的销毁方法,那么Spring将执行Bean的这个方法,完成Bean资源的释放等操作。

Bean的完整生命周期从Spring容器着手实例化Bean开始,直到最终销毁Bean。其中经历了许多关键点,每个关键点都涉及特定方法的调用,可以将这些方法大致划分为4类。

  • Bean自身的方法:如调用Bean构造函数实例化Bean、调用Setter设置Bean的属性值及通过的init-method和destroy-method所指定的方法。
  • Bean级生命周期接口方法:如BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean,这些接口方法Bean类直接实现。
  • 容器级生命周期接口方法:InstantiationAwareBeanPostProcessor和BeanPostProcessor。一般称它们的实现类为”后处理器“。后处理器接口一般不由Bean本身实现,它们独立于Bean,实现类以容器附加装置的形式注册到Spring容器中,并通过接口反射为Spring容器扫描识别。当Spring容器创建任何Bean的时候,这些后处理器都会发生作用,所以这些后处理器的影响是全局性的。当然,用户可以通过合理地编写后处理器,让其仅对感兴趣的Bean进行加工处理。
  • 工厂后处理器接口方法:包括AspectJWeavingEnabler、CustomAutowireConfigurer和ConfigurationClassPostProcessor等方法。工厂后处理器也是容器级的,在应用上下文装配配置文件后立即调用。

Bean级生命周期接口和容器级生命周期接口是个性和共性辩证统一思想的体现,前者解决Bean个性化处理的问题,而后者解决容器中某些Bean共性化处理的问题。

Spring中是否可以注册多个后处理器呢?答案是肯定的。只要它们同时实现org.springframework.core.Ordered接口,容器将按特定的顺序依次调用这些后处理器。

InstantiationAwareBeanPostProcessor其实是BeanPostProcessor接口的子接口,Spring为其提供了一个适配器类InstantiationAwareBeanPostProcessorAdapter,一般情况下,可以方便地扩展该适配器覆盖特定的方法以定义特定的实现类。

ApplicationContext中Bean的生命周期

Bean在应用上下文中的生命周期和在BeanFactory中的生命周期类似,不同的是,如果Bean实现了
org.springframework.context.ApplicationContextAware接口,则会增加一个调用该接口方法的setApplicationContext()的步骤。

此外,如果在配置文件中声明了工厂后处理器接口的BeanFactoryPostProessor的实现类,则应用上下文在装载配置文件之后、初始化Bean实例之前将调用这些BeanFactoryPostProcessor对配置信息进行加工处理。

ApplicationContext和BeanFactory一个最大的不同之处在于:前者会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而后者需要在代码中通过手工调用addBeanPostProcessor()方法进行注册。

参考

《精通Spring 4.x 企业应用开发实战》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章