文章内容引用自 咕泡科技
咕泡出品,必属精品
文章目录
1. 应付面试
你若是真的为面试而来,请把下面这段背下来,应付面试足矣
spring的bean的生命周期主要是创建bean的过程,一个bean的生命周期主要是4个步骤,
实例化,属性注入,初始化,销毁
但是对于一些复杂的bean的创建,spring会在bean的生命周期中开放很多的接口,可以让你加载bean的时候对bean做一些改变,因此spring的bean的生命周期总共有以下几步:
首先在spring中有一些特殊的bean会介入到其他bean的声明周期当中去,所以一个普通的bean的生命周期为:
- 实现了BeanFactoryPostProcessor接口的bean,在加载其他的bean的时候,也会调用这个bean的
postProcessBeanFactory方法,可以在这个步骤去对bean中的属性去赋值。设置年龄初始化18等等。
- 实现了InstantiationAwareBeanPostProcessor接口的bean,会在实例化bean之前调用
postProcessBeforeInstantiation方法
- 然后在对bean进行实例化
- 对bean进行属性注入
- 对bean进行初始化,在初始化中,包含了以下几个步骤:
1. 实现了BeanFactoryAware接口,会先调用setBeanFactory方法
2. 实现了BeanNameAware接口,会先调用setBeanName方法
3. 实现了BeanPostProcessor接口,会先调用postProcessBeforeInitialization方法
3. 实现了InitializingBean接口,会调用afterPropertiesSet方法
4. 然后在进行aop后置处理,通过实现BeanPostProcessor接口,在postProcessAfterInitialization方法中进行动态代理
- 销毁
2 可以跟着看源码的图
Bean的生命周期主要是Bean的创建过程,使用和销毁都比较简单
如上所说大致可以分为四个阶段:
实例化 -> 属性赋值 -> 初始化 -> 销毁
给出一个可以让你们看着去跟源码一步一步点下去的无敌图
其实学习Bean的生命周期有这个图就足够了
本图来自咕泡学院文泰老师,转发请注明出处,否则必究
咕泡出品,必属精品
3 学习Bean 的生命周期之前你应该知道什么
没有前置知识盲目的去学习Bean的生命周期,是没有任何意义的,或者说这只是为了应付面试而学
没有使用场景,没有复习欲望,看完背完你能记多久呢?
一周?一个月?
你大学学的计算机网络你还记得吗(手动滑稽)
在学习Bean的生命周期之前,你至少应该知道、或者大概知道Spring IOC和DI,知道他们的详细流程,Spring容器的初始化流程,AOP的代码织入过程,有兴趣的还可以学习一下Spring是如何解决循环依赖的,以及Spring中的经典代码
学习完上述知识之后,你已经对Spring有了一个基本还算完善的概念,这时你也知道了一个Bean在容器初始化的时候经历了什么,然后再去系统的学习一个Bean完整的生命流程,对照你已经学习的知识,查漏补缺。
学习Spring和看Spring源码一定要先学思想!!!
学习Spring和看Spring源码一定要先学思想!!!
学习Spring和看Spring源码一定要先学思想!!!
4 Bean 的完整生命周期
在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。
相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强
对上图的每一个步骤解释一下下
- Spring启动,查找并加载需要被Spring管理的bean,进行Bean的实例化
- Bean实例化后对将Bean的引入和值注入到Bean的属性中
- 如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法
- 如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入
- 如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来。
- 如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。
- 如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用
- 如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。
- 此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。
- 如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。
上面是Spring 中Bean的核心接口和生命周期,面试回答上述过程已经足够了。但是翻阅JavaDoc文档发现除了以上接口外,还有另外的初始化过程涉及的接口:
摘自org.springframework.beans.factory.BeanFactory,
全部相关接口如下,上述已有的就不用着重标注,把额外的相关接口着重标注下
解释一下上图:
创建过程:
- BeanNameAware.setBeanName() 在创建此bean的bean工厂中设置bean的名称,在普通属性设置之后调用,在InitializinngBean.afterPropertiesSet()方法之前调用
BeanClassLoaderAware.setBeanClassLoader():
在普通属性设置之后,InitializingBean.afterPropertiesSet()之前调用- BeanFactoryAware.setBeanFactory() : 回调提供了自己的bean实例工厂,在普通属性设置之后,在InitializingBean.afterPropertiesSet()或者自定义初始化方法之前调用
EnvironmentAware.setEnvironment()
: 设置environment在组件使用时调用EmbeddedValueResolverAware.setEmbeddedValueResolver()
: 设置StringValueResolver 用来解决嵌入式的值域问题ResourceLoaderAware.setResourceLoader()
: 在普通bean对象之后调用,在afterPropertiesSet 或者自定义的init-method 之前调用,在 ApplicationContextAware 之前调用。ApplicationEventPublisherAware.setApplicationEventPublisher()
: 在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用。在 ApplicationContextAware 之前调用。MessageSourceAware.setMessageSource()
: 在普通bean属性之后调用,在初始化调用afterPropertiesSet 或者自定义初始化方法之前调用,在 ApplicationContextAware 之前调用。- ApplicationContextAware.setApplicationContext(): 在普通Bean对象生成之后调用,在InitializingBean.afterPropertiesSet之前调用或者用户自定义初始化方法之前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware之后调用。
ServletContextAware.setServletContext()
: 运行时设置ServletContext,在普通bean初始化后调用,在InitializingBean.afterPropertiesSet之前调用,在 ApplicationContextAware 之后调用注:是在WebApplicationContext 运行时- BeanPostProcessor.postProcessBeforeInitialization() : 将此BeanPostProcessor 应用于给定的新bean实例 在任何bean初始化回调方法(像是InitializingBean.afterPropertiesSet或者自定义的初始化方法)之前调用。这个bean将要准备填充属性的值。返回的bean示例可能被普通对象包装,默认实现返回是一个bean。
- BeanPostProcessor.postProcessAfterInitialization() : 将此BeanPostProcessor 应用于给定的新bean实例 在任何bean初始化回调方法(像是InitializingBean.afterPropertiesSet或者自定义的初始化方法)之后调用。这个bean将要准备填充属性的值。返回的bean示例可能被普通对象包装
- InitializingBean.afterPropertiesSet(): 被BeanFactory在设置所有bean属性之后调用(并且满足BeanFactory 和 ApplicationContextAware)。
销毁:
DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()
: 在销毁之前将此BeanPostProcessor 应用于给定的bean实例。能够调用自定义回调,像是DisposableBean 的销毁和自定义销毁方法,这个回调仅仅适用于工厂中的单例bean(包括内部bean)- 实现了自定义的destory()方法