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

相关推荐
我真会写代码5 小时前
SSM(指南一)---Maven项目管理从入门到精通|高质量实操指南
java·spring·tomcat·maven·ssm
vx_Biye_Design5 小时前
【关注可免费领取源码】房屋出租系统的设计与实现--毕设附源码40805
java·spring boot·spring·spring cloud·servlet·eclipse·课程设计
独断万古他化8 小时前
【SSM开发实战:博客系统】(三)核心业务功能开发与安全加密实现
spring boot·spring·mybatis·博客系统·加密
若鱼19198 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
跳动的梦想家h9 小时前
环境配置 + AI 提效双管齐下
java·vue.js·spring
独断万古他化10 小时前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
vx1_Biye_Design11 小时前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
Hx_Ma1611 小时前
SpringBoot数据源自动管理
java·spring boot·spring
java1234_小锋11 小时前
Java高频面试题:Spring和SpringBoot的关系和区别?
java·spring boot·spring
梵得儿SHI12 小时前
(第十篇)Spring AI 核心技术攻坚全梳理:企业级能力矩阵 + 四大技术栈攻坚 + 性能优化 Checklist + 实战项目预告
java·人工智能·spring·rag·企业级ai应用·springai技术体系·多模态和安全防护