在 Bean生命周期(一) 浅尝知味 中,我们介绍了Bean的生命周期,并通过实验对其进行了验证,这次我们将从源码角度对其做进一步说明。整个Bean的生命周期,主要的逻辑就是实例化、初始化、销毁,而这些逻辑都集中在两个类里面,一个是 AbstractAutowireCapableBeanFactory
,负责Bean的实例化与初始化,另外一个是 DisposableBeanAdapter
,负责Bean的整个销毁流程。
Bean的创建
Bean的创建主要包括实例化与初始化两个阶段,都包含在 AbstractAutowireCapableBeanFactory
的 createBean()
的方法中。
实例化
实例化指创建Bean实例的过程,这里泛指创建Bean及其前后 InstantiationAwareBeanPostProcessor
相关方法的调用,即 Bean生命周期(一) 浅尝知味 中的第一条支线。
首先,看下 createBean()
方法,由于篇幅的原因,只贴出部分核心的代码,其它部分都将使用省略号进行代替。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
.......
try {
// 此处会调用 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation()
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 剩下所有的步骤都在这个方法里面
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
整个方法里面主要包含了两部分逻辑:
-
在创建Bean之前,通过
resolveBeforeInstantiation()
方法对InstantiationAwareBeanPostProcessor
的postProcessBeforeInstantiation()
方法进行了调用; -
调用
doCreateBean()
方法,该方法包含了除第一部分以外所有创建Bean的逻辑。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 实例化Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 调用Bean的构造方法
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
......
// 初始化Bean实例
Object exposedObject = bean;
try {
// 调用 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation() 方法
populateBean(beanName, mbd, instanceWrapper);
// 完成Bean实例的初始化流程
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
......
return exposedObject;
}
在 doCreateBean()
方法里面,又分为两部分:
-
实例化Bean对象,通过反射调用Bean对象的构造方法,对其进行实例化,创建一个Bean实例。
-
初始化Bean实例
- 通过
populateBean()
方法完成对InstantiationAwareBeanPostProcessor
的postProcessAfterInstantiation()
方法调用。 - 调用
initializeBean()
完成剩余所有初始化动作。
- 通过
至此,创建Bean流程的第一条线已经完成,用一个简单的时序图做一个阶段性的小结。
初始化
初始化的流程指Bean创建完成后,Aware
及 BeanPostProcessor
相关钩子方法的调用,可以完成Bean对象基本的初始化动作。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 一、调用 BeanNameAware 的 setBeanName() 方法
// 二、调用 BeanFactoryAware 的 setBeanFactory() 方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 一、调用 ApplicationContextAware 的 setApplicationContext() 方法
// 二、调用自定义的 BeanPostProcessor 的 postProcessBeforeInitialization() 方法
// 三、调用 @PostConstruct 注解标注的方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 一、调用 InitializingBean 的 afterPropertiesSet() 方法
// 二、调用 <bean> 配置中 init-method 指向的方法 或 @Bean 注解中 initMethod 配置指向的方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 调用自定义的 BeanPostProcessor 的 postProcessAfterInitialization() 方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
initializeBean()
方法可以分解成四个部分:
- 通过
invokeAwareMethods()
方法完成对BeanNameAware
、BeanFactoryAware
的调用。 - 通过
applyBeanPostProcessorsBeforeInitialization()
方法完成对ApplicationContextAware
、BeanPostProcessor.postProcessBeforeInitialization()
、@PostConstruct
的调用。 - 通过
invokeInitMethods()
方法完成对InitializingBean
、init-method
关联方法的调用。 - 通过
applyBeanPostProcessorsAfterInitialization()
完成对BeanPostProcessor.postProcessAfterInitialization()
方法调用。
在 invokeAwareMethods()
方法里面,除了调用 BeanNameAware
、BeanFactoryAware
外,还调用了 BeanClassLoaderAware
的 setBeanClassLoader()
方法。
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
这里,有一点需要注意的是,ApplicationContextAware
并没有在 invokeAwareMethods()
里面调用。而是在 applyBeanPostProcessorsBeforeInitialization()
通过调用 ApplicationContextAwareProcessor
的 postProcessBeforeInitialization()
方法实现的。 ApplicationContextAwareProcessor
的实现逻辑如下:
class ApplicationContextAwareProcessor implements BeanPostProcessor {
.....
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
// 调用 ApplicationContextAware 的 setApplicationContext() 方法
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
在 ApplicationContextAwareProcessor
的实现里面,还调用了 EnvironmentAware
、EmbeddedValueResolverAware
、ResourceLoaderAware
、ApplicationEventPublisherAware
、MessageSourceAware
等钩子接口。而在 postProcessAfterInitialization()
未做任何处理,这使得在后面触发该方法调用时不会产生任何影响。
还有另外一个值得注意的地方是 @PostConstruct
也并未在 invokeInitMethods()
方法中调用,而是与 ApplicationContextAware
一样,使用 BeanPostProcessor
的方式实现,它对应的实现类是 InitDestroyAnnotationBeanPostProcessor
,此类除了 BeanPostProcessor
接口外,还实现了 DestructionAwareBeanPostProcessor
接口,并在此接口定义的方法中完成了对 @PreDestroy
的处理。具体的实现如下:
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 调用 @PostConstruct
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
// 调用 @PreDestroy
metadata.invokeDestroyMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex.getTargetException());
}
else {
logger.warn(msg + ": " + ex.getTargetException());
}
}
catch (Throwable ex) {
logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
}
}
}
在 applyBeanPostProcessorsBeforeInitialization()
方法里,除了ApplicationContextAware
,@PostConstruct
以外,主要是调用了 BeanPostProcessor
的 postProcessBeforeInitialization()
方法。
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 调用 InitializingBean 的 afterPropertiesSet() 方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 调用 <bean> 的 init-method 或 @Bean 的 initMethod 指定的方法
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
在 invokeInitMethods()
方法中,完成了如下两件事情:
- 调用
InitializingBean
的afterPropertiesSet()
方法 - 调用
<bean>
的init-method
或@Bean
的initMethod
指定的方法
最后的 applyBeanPostProcessorsAfterInitialization()
方法,不再多做介绍,与 applyBeanPostProcessorsBeforeInitialization()
类似,完成对 BeanPostProcessor.postProcessAfterInitialization()
方法的调用。
同样,在最后,我们使用时序图对初始化流程做下小结
Bean 销毁
Bean 销毁的流程全部在 DisposableBeanAdapter
的 destroy()
方法里面,流程比较简单,直接上代码
public void destroy() {
// 调用 @PreDestroy
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// 调用 DisposableBean 的 destroy() 方法
if (this.invokeDisposableBean) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
}
try {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((DisposableBean) this.bean).destroy();
return null;
}, this.acc);
}
else {
((DisposableBean) this.bean).destroy();
}
}
catch (Throwable ex) {
String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
if (logger.isDebugEnabled()) {
logger.warn(msg, ex);
}
else {
logger.warn(msg + ": " + ex);
}
}
}
// 调用 <bean> 的 destroy-method 或 @Bean 的 destroyMethod 指定的方法
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
destroy()
方法的主要逻辑如下:
- 通过
InitDestroyAnnotationBeanPostProcessor
实现DestructionAwareBeanPostProcessor
接口,完成对@PreDestroy
标注方法的调用 - 调用
DisposableBean
的destroy()
方法 - 调用
<bean>
的destroy-method
或@Bean
的destroyMethod
指定的方法
Bean销毁流程的时序图整理如下:
欢迎您扫一扫上面的微信公众号,订阅我的博客!