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

相关推荐
杨杨杨大侠17 小时前
RAG 到底是怎么工作的?从用户提问到模型回答的完整链路
spring·openai·ai编程
Joy T17 小时前
Spring AI 2.0 Agent 进阶:Memory、State 与 Context Engineering 常见技术全景
java·人工智能·后端·spring·agent入门·agent state
wno70420 小时前
Spring Security短信验证码登录
java·python·spring
步行cgn20 小时前
Spring util 命名空间详解
java·后端·spring
MayBaymax1 天前
Spring AI Alibaba Graph 快速上手:黑板、节点、边
java·spring·ai·ai编程
acd120091 天前
Java 线程池线上高频踩坑记录
spring
苏渡苇1 天前
Spring Insight 里如何把 Span 收成一条链路
spring boot·spring·spring cloud·系统监控·apm
小尹哥-程序员1 天前
第4集:让AI学会看文档:Spring AI RAG入门实战
java·人工智能·spring
叶总没有会1 天前
微服务--分布式基础
java·spring·spring cloud·微服务
考虑考虑2 天前
Springboot环境变量占位符语法
spring boot·后端·spring