本文作用
本文主要是为了说明Spring Bean的生命周期。这是一个高频面试题,这个问题即考察对Spring的微观了解,又考察对Spring的宏观认识,还考察对Spring源码的熟悉程度!
宏观认识
Bean的生命周期宏观上可以表达为:
- Bean工厂初始化(不熟的,这部分可以不提)
- 实例化-Instantiation
- 属性赋值-populate
- 初始化-Initialization
- 销毁-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源码的摘录。大家本地有源码的朋友,可以把鼠标放到类名字上面去,就可以预览注释的实际效果了。
java
/**
* Bean工厂的根父类,定义获取bean及bean的各种属性。下面的注释中还列举了Bean的生命周期 <br>
* The root interface for accessing a Spring bean container.
*
* <p>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.
*
* <p>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).
*
* <p>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.
*
* <p>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.
*
* <p>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).
*
* <p>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.
*
* <p>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:
* <ol>
* <li>BeanNameAware's {@code setBeanName}
* <li>BeanClassLoaderAware's {@code setBeanClassLoader}
* <li>BeanFactoryAware's {@code setBeanFactory}
* <li>EnvironmentAware's {@code setEnvironment}
* <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
* <li>ResourceLoaderAware's {@code setResourceLoader}
* (only applicable when running in an application context)
* <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
* (only applicable when running in an application context)
* <li>MessageSourceAware's {@code setMessageSource}
* (only applicable when running in an application context)
* <li>ApplicationContextAware's {@code setApplicationContext}
* (only applicable when running in an application context)
* <li>ServletContextAware's {@code setServletContext}
* (only applicable when running in a web application context)
* <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
* <li>InitializingBean's {@code afterPropertiesSet}
* <li>a custom init-method definition
* <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
* </ol>
*
* <p>On shutdown of a bean factory, the following lifecycle methods apply:
* <ol>
* <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
* <li>DisposableBean's {@code destroy}
* <li>a custom destroy-method definition
* </ol>
*
* @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生命周期
- BeanNameAware's setBeanName
- BeanClassLoaderAware's setBeanClassLoader
- BeanFactoryAware's setBeanFactory
- EnvironmentAware's setEnvironment
- EmbeddedValueResolverAware's setEmbeddedValueResolver
- ResourceLoaderAware's setResourceLoader (only applicable when running in an application context)
- ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context)
- MessageSourceAware's setMessageSource (only applicable when running in an application context)
- ApplicationContextAware's setApplicationContext (only applicable when running in an application context)
- ServletContextAware's setServletContext (only applicable when running in a web application context)
- postProcessBeforeInitialization methods of BeanPostProcessors
- InitializingBean's afterPropertiesSet
- a custom init-method definition
- postProcessAfterInitialization methods of BeanPostProcessors
在关闭bean工厂时,也就是销毁时,应用以下生命周期方法:
- DestructionAwareBeanPostProcessors.postProcessBeforeDestruction()
- DisposableBean的destroy方法
- 自定义的destroy-method
参考说明
https://zhuanlan.zhihu.com/p/622803858?utm_id=0
https://www.mashibing.com/study?courseNo=2154\§ionNo=36480\&courseVersionId=1241