赞
踩
单例对象在加载Spring配置文件的时候就创建出来了,非单例对象在每一次使用的时候通过getBean创建。
容器关闭之前,调用bean的销毁方法。
实例化bean对象(通过工厂),设置对象属性(依赖注入),调用Bean的Id传入工厂,调用Bean的初始化方法,使用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接口,调用预初始化方法
如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调
如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法
此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁
如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用
主要有这4个阶段:
1.
实例化
Instantiation
2.属性赋值
Populate
3.初始化
Initialization
4.销毁
Destruction
时序图:
几个重要的接口和类:
BeanFactoryPostProcessor
接口
InstantiationAwareBeanPostProcessor
接口
BeanPostProcessor
接口
AbstractAutowireCapableBeanFactory
类
实例化
和属性赋值
对应构造方法
和setter方法
的注入
,初始化和销毁是能自定义扩展的两个阶段。 主要逻辑都在AbstractAutowireCapableBeanFactory
的doCreateBean()
方法中。
首先来看AbstractAutowireCapableBeanFactory
所处的位置
doCreateBean()
方法逻辑很清晰,就是顺序调用以下三个方法,这三个方法与三个生命周期阶段一一对应
// 此代码忽略了一些无关代码
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 实例化
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
try {
// 属性赋值
this.populateBean(beanName, mbd, instanceWrapper);
// 初始化
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
}
}
Spring生命周期相关的常用扩展点非常多 ,
实现了这些接口的Bean会切入到多个Bean的生命周期中
。正因为如此,这些接口的功能非常强大,Spring内部扩展也经常使用这些接口,例如自动注入以及AOP的实现都和他们有关
。
BeanPostProcessor
InstantiationAwareBeanPostProcessor
这两父子
可能是Spring扩展中最重要的两个接口!InstantiationAwareBeanPostProcessor
作用于实例化阶段的前后
,BeanPostProcessor
作用于初始化阶段的前后
。正好和第一、第三个生命周期阶段对应。
InstantiationAwareBeanPostProcessor实际上继承了BeanPostProcessor接口
InstantiationAwareBeanPostProcessor extends BeanPostProcessor
这一大类接口的特点是功能丰富,常用于用户自定义扩展。
第二大类中又可以分为两类:
1. Aware类型的接口
2. 生命周期接口
Spring之所有有一堆Aware接口,主要为了给开发者留下嵌入点,在Bean的生命周期过程中做很多操作。
如下面两幅图在初始化阶段调用 Aware类型的接口
Aware类型的接口
的作用就是让我们能够拿到Spring容器中的一些资源
,。Aware之前的名字就是可以拿到什么资源,BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
。例如BeanNameAware
可以拿到BeanName
这里把Aware接口分为两组,因为调用
Aware Group1
BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
Aware Group2
EnvironmentAware
EmbeddedValueResolverAware 这个知道的人可能不多,实现该接口能够获取Spring EL解析器,用户的自定义注解需要支持spel表达式的时候可以使用,非常方便。
ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的ApplicationContext对象,因为ApplicationContext是一个复合接口,如下:
详情如下,忽略了部分无关代码。代码位置就是我们上文提到的initializeBean方法详情,这也说明了Aware都是在初始化阶段之前调用的
!
// 见名知意,初始化阶段调用的方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 这里调用的是Group1中的三个Bean开头的Aware
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
// 这里调用的是Group2中的几个Aware,
// 而实质上这里就是前面所说的BeanPostProcessor的调用点!
// 也就是说与Group1中的Aware不同,这里是通过BeanPostProcessor(ApplicationContextAwareProcessor)实现的。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 下文即将介绍的InitializingBean调用点
invokeInitMethods(beanName, wrappedBean, mbd);
// BeanPostProcessor的另一个调用点
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
可以看到并不是所有的Aware接口都使用同样的方式调用。
Bean××Aware都是在代码中直接调用的,而ApplicationContext相关的Aware都是通过BeanPostProcessor#postProcessBeforeInitialization()实现的
。感兴趣的可以自己看一下ApplicationContextAwareProcessor这个类的源码,就是判断当前创建的Bean是否实现了相关的Aware方法,如果实现了会调用回调方法将资源传递给Bean。
BeanPostProcessor的调用时机也能在这里体现,包围住invokeInitMethods方法,也就说明了在初始化阶段的前后执行。
至于剩下的两个生命周期接口就很简单了,实例化和属性赋值都是Spring帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段。
InitializingBean
对应生命周期的初始化阶段
,在上面源码的invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。
有一点需要注意,因为Aware方法都是执行在初始化方法之前,所以可以在初始化方法中放心大胆的使用Aware接口获取的资源,这也是我们自定义扩展Spring的常用方式
。
DisposableBean
类似于InitializingBean,对应生命周期的销毁阶段
,以ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了DisposableBean接口的Bean然后调用其destroy()方法 。
Spring Bean的生命周期分为四个阶段
和多个扩展点
。
扩展点又可以分为默认的Bean处理接口
和可以自定义的Bean拓展处理接口
实例化 Instantiation
属性赋值 Populate
初始化 Initialization
销毁 Destruction
BeanPostProcessor
InstantiationAwareBeanPostProcessor
Aware
BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
EnvironmentAware
EmbeddedValueResolverAware
ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
生命周期
InitializingBean
DisposableBean
参数校验功能中,使用过ApplicationContextAware来获取到ApplicationContext,使用ApplicationContext的方法
去看看
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。