Spring源码-面试题-Bean的生命周期

本文作用

本文主要是为了说明Spring Bean的生命周期。这是一个高频面试题,这个问题即考察对Spring的微观了解,又考察对Spring的宏观认识,还考察对Spring源码的熟悉程度!

宏观认识

Bean的生命周期宏观上可以表达为:

  1. Bean工厂初始化(不熟的,这部分可以不提)
  2. 实例化-Instantiation
  3. 属性赋值-populate
  4. 初始化-Initialization
  5. 销毁-Destruction

有的人可能会疑惑,Bean工厂和Bean是两回事,为什么会和Bean的生命周期有关?

  • Bean工厂中存放了BeanDefinition,这个就是Bean的定义,Bean就是根据这个实例化出来的。
  • Bean工厂初始化的时候会调用一个特殊的后置处理器:ConfigurationClassPostProcessor。他会解析如下注解。
    • @Configuration的配置类
    • 解析@ComponentScan扫描的包
    • 解析@Import注解
  • 从上可以看出,这个Bean工厂的实例化也和Bean的生命周期有关系的。
  • 下面就用这个完整的Bean生命周期流程图来说明。(使用mermaid语法绘制)
Bean工厂初始化
销毁-Destruction
自定义的destoryMethod
DestructionAwareBeanPostProcessors
.postProcessBeforeDestruction()
DisposableBean
.destroy()
初始化
invokeAwareMethod
BeanFactoryAware
BeanNameAware
BeanClassLoaderAware
执行BPP的before方法
ApplicationAwarePostPRocessor
ApplicationContextAware
EnvironmentAware
EmbeddedValueResolverAware
ResourceLoaderAware
ApplicationEventPublisherAware
MessageSourceAware
CommonAnnotationBeanPostProcessor
负责解析@Resource、@WebServiceRef
、@EJB三个注解,这三个注解定义在javax.*包下
invokeInitMethod
执行用户自定义的init-method
InitializingBean.afterPropertiesSet
执行BFF的after方法
AOP
属性赋值
依赖对象创建
属性填充
实例化
applyMergedBeanDefinitionPostProcessors
doGetBean
createBean
doCreateBean
createBeanInstance
beanFactory的准备工作,对他里面的BeanDefinition的各种属性进行填充(prepareBeanFactory)
加载配置文件,创建容器对象(obtainFreshBeanFactory)
调用各种beanFactory处理器(invokeBeanFactoryPostProcessors)
解析@Import注解
ConfigurationClassPostProcessor
解析@Configuration的配置类
解析@ComponentScan扫描的包
配置文件,注解,启动类
完成BeanPostProcessor的注册工作,以便后续在实例化完成之后调用before和after方法
Bean创建总方法(finishBeanFactoryInitialization)

Spring源码

其实在Spring源码的BeanFactory这个类的注释中,Spring源码的作者已经告诉我们Bean完整的生命周期了。

下面就是Spring源码的摘录。大家本地有源码的朋友,可以把鼠标放到类名字上面去,就可以预览注释的实际效果了。

/**
 * Bean工厂的根父类,定义获取bean及bean的各种属性。下面的注释中还列举了Bean的生命周期 
* The root interface for accessing a Spring bean container. * *

This is the basic client view of a bean container; * further interfaces such as {@link ListableBeanFactory} and * {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} * are available for specific purposes. * *

This interface is implemented by objects that hold a number of bean definitions, * each uniquely identified by a String name. Depending on the bean definition, * the factory will return either an independent instance of a contained object * (the Prototype design pattern), or a single shared instance (a superior * alternative to the Singleton design pattern, in which the instance is a * singleton in the scope of the factory). Which type of instance will be returned * depends on the bean factory configuration: the API is the same. Since Spring * 2.0, further scopes are available depending on the concrete application * context (e.g. "request" and "session" scopes in a web environment). * *

The point of this approach is that the BeanFactory is a central registry * of application components, and centralizes configuration of application * components (no more do individual objects need to read properties files, * for example). See chapters 4 and 11 of "Expert One-on-One J2EE Design and * Development" for a discussion of the benefits of this approach. * *

Note that it is generally better to rely on Dependency Injection * ("push" configuration) to configure application objects through setters * or constructors, rather than use any form of "pull" configuration like a * BeanFactory lookup. Spring's Dependency Injection functionality is * implemented using this BeanFactory interface and its subinterfaces. * *

Normally a BeanFactory will load bean definitions stored in a configuration * source (such as an XML document), and use the {@code org.springframework.beans} * package to configure the beans. However, an implementation could simply return * Java objects it creates as necessary directly in Java code. There are no * constraints on how the definitions could be stored: LDAP, RDBMS, XML, * properties file, etc. Implementations are encouraged to support references * amongst beans (Dependency Injection). * *

In contrast to the methods in {@link ListableBeanFactory}, all of the * operations in this interface will also check parent factories if this is a * {@link HierarchicalBeanFactory}. If a bean is not found in this factory instance, * the immediate parent factory will be asked. Beans in this factory instance * are supposed to override beans of the same name in any parent factory. * *

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

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

    *
  1. {@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors *
  2. DisposableBean's {@code destroy} *
  3. a custom destroy-method definition *
* * @author Rod Johnson * @author Juergen Hoeller * @author Chris Beams * @since 13 April 2001 * @see BeanNameAware#setBeanName * @see BeanClassLoaderAware#setBeanClassLoader * @see BeanFactoryAware#setBeanFactory * @see org.springframework.context.ResourceLoaderAware#setResourceLoader * @see org.springframework.context.ApplicationEventPublisherAware#setApplicationEventPublisher * @see org.springframework.context.MessageSourceAware#setMessageSource * @see org.springframework.context.ApplicationContextAware#setApplicationContext * @see org.springframework.web.context.ServletContextAware#setServletContext * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization * @see InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization * @see DisposableBean#destroy * @see org.springframework.beans.factory.support.RootBeanDefinition#getDestroyMethodName */
public interface BeanFactory { //...... 此处省略代码细节 }

根据这个注释,我们也可以整理出一份简易文字版bean生命周期

  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

在关闭bean工厂时,也就是销毁时,应用以下生命周期方法:

  1. DestructionAwareBeanPostProcessors.postProcessBeforeDestruction()
  2. DisposableBean的destroy方法
  3. 自定义的destroy-method

参考说明

https://zhuanlan.zhihu.com/p/622803858?utm_id=0

https://www.mashibing.com/study?courseNo=2154§ionNo=36480&courseVersionId=1241

你可能感兴趣的:(Java框架,Java,spring,源码分析,Bean生命周期)