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源码的摘录。大家本地有源码的朋友,可以把鼠标放到类名字上面去,就可以预览注释的实际效果了。

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生命周期

  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\&sectionNo=36480\&courseVersionId=1241

相关推荐
智慧老师28 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
hanbarger3 小时前
mybatis框架——缓存,分页
java·spring·mybatis
龙少95436 小时前
【深入理解@EnableCaching】
java·后端·spring
啦啦右一12 小时前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
荆州克莱15 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei15 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
火烧屁屁啦16 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee
岁岁岁平安16 小时前
spring学习(spring-DI(字符串或对象引用注入、集合注入)(XML配置))
java·学习·spring·依赖注入·集合注入·基本数据类型注入·引用数据类型注入
北辰浮光16 小时前
[spring]XML配置文件标签
xml·spring
ZSYP-S17 小时前
Day 15:Spring 框架基础
java·开发语言·数据结构·后端·spring