这是我参与更文挑战的第4天,活动详情查看: 更文挑战
对于java程序员来说,spring框架是面试中永远绕不开的话题,而在spring的一系列面试题中,spring bean的生命周期又是很多面试官非常喜欢问的。今天我们就来学习一下spring bean的生命周期。
先看下整体的流程图:
相信很多人在网上或多或少见过和这张类似的流程图,但这样看上去其实特别繁琐,不好记忆。
按我个人的理解,我觉得spring bean的生命周期可以分为四个阶段:
- bean的实例化(通过java反射方式生成对象)
- bean的属性赋值(PopulateBean()这个阶段其实会涉及到很多的问题,比如我们之前聊过的循环依赖问题和spring是怎样通过三级缓存的设计解决的,面试的时候都可以展开和面试官聊聊)
- bean的初始化(initializeBean)
- bean的销毁
上述流程除了第四部bean的销毁,其余逻辑几乎都在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
方法中体现:
看下源码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
if (instanceWrapper == null) {
//实例化对象,里面第二次调用后置处理器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
//属性填充,也就是我们常常说的自动注入
//里面会完成第五次和第六次后置处理器的调用
populateBean(beanName, mbd, instanceWrapper);
//初始化spring
//里面会进行第七次和第八次的后置处理器的调用
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
复制代码
忽略了不相关的代码
图中在bean的属性填充之后,初始化之前做了哪些扩展性增强呢?
照例看下源码:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//调用aware接口的相关方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessor的前置处理方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用InitMehod方法
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的后置处理方法 aop就是在此处实现的
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
通过源码我们可以很清晰的看到在bean完成真正的初始化之前都做了哪些工作
- 调用aware接口的相关方法 invokeAwareMethods(beanName, bean);(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)
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);
}
}
}
复制代码
- 调用BeanPostProcessor的前置处理方法 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
复制代码
- 调用InitMehod方法: invokeInitMethods(beanName, wrappedBean, mbd);
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
//如果实现了InitializingBean接口,执行他的afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
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);
}
}
}
复制代码
- 调用BeanPostProcessor的后置处理方法: applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
复制代码
这之后bean的初始化完成,就保存在spring应用的上下文当中,可以通过getBean的方式来调用,直到关闭,才会被销毁。
以上,感谢阅读。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END