https://cloud.tencent.com/developer/article/2284060
### -------doCreateBean------------initializeBean
initializeBean方法主要是针对我们配置的init-method属性,当Spring中程序已经执行过bean的实例化,
并且进行了属性的填充,而就在这时将会调用用户设定的初始化方法。具体源码如下所示:
-> AbstractAutowireCapableBeanFactory.initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean); 激活Aware方法
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic())
调用配置的所有BeanPostProcessor#postProcessBeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
try {
invokeInitMethods(beanName, wrappedBean, mbd); 激活用户自定义的init方法
} catch (Throwable ex) {throw new BeanCreationException(...);}
if (mbd == null || !mbd.isSynthetic())
调用配置的所有BeanPostProcessor#postProcessAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
invokeAwareMethods(...)激活Aware方法 ???
Spring中提供了一些Aware接口实现,比如:BeanFactoryAware、ApplicationContextAware、
ResourceLoaderAware、ServletContextAware等,
实现这些Aware接口的bean在被初始化之后,可以取得一些相对的资源。
invokeInitMethods(...)激活自定义的init方法
客户定制的初始化方法除了我们熟知的使用配置init-method外,
还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet()方法中实现自己的初始化业务逻辑。
其中,InitializingBean的afterPropertiesSet()方法先被执行,而init-method后执行。下面是相关源码实现:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) logger.trace(...);
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet(); // 属性初始化后的处理
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {throw pae.getException();}
}
// 属性初始化后的处理,调用InitializingBean#afterPropertiesSet()方法
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)) {
// 调用自定义的init-method方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd) throws Throwable {
String initMethodName = mbd.getInitMethodName(); 获得init-method方法
Assert.state(initMethodName != null, "No init method set");
/** 步骤1:获得init-method对应的Method实例对象 */
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null)
if (mbd.isEnforceInitMethod()) throw new BeanDefinitionValidationException(...);
else return;
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
/** 步骤2:通过反射,执行init-method的方法调用 */
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
} catch (PrivilegedActionException pae) {...}
}
else {
try {
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean); 通过反射,执行init-method的方法调用
}
catch (InvocationTargetException ex) {throw ex.getTargetException();}
}
}
registerDisposableBeanIfNecessaryn(...)注册DisposableBean
Spring同时也提供了销毁方法的扩展入口,对于销毁方法的扩展,除了我们熟知的配置属性destroy-method方法外,
用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法,具体源码如下所示:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
/**
* 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
* 并且对所有的bean使用DestructionAwareBeanPostProcessor处理
*/
if (mbd.isSingleton())
registerDisposableBean(beanName, new DisposableBeanAdapter(bean,
beanName,
mbd,
getBeanPostProcessorCache().destructionAware,
acc));
else { // 自定义scope的处理
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) throw new IllegalStateException(...);
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean,
beanName,
mbd,
getBeanPostProcessorCache().destructionAware,
acc));
}
}
}
/**
* AbstractAutoProxyCreator类中的bean后置处理器中的后方法
*/
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 有AOP的情况下会调用getEarlyBeanReference方法,在getEarlyBeanReference方法中会将原本的bean放入到earlyProxyReferences中,
所以remove出来的bean和参数中的bean是同一个,条件不成立,所以不会再生成一个新的代理对象
// 如果没有aop,就不会调用getEarlyBeanReference方法,earlyProxyReferences是空的,remove出来是null,条件成立,就会生成一个代理对象
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}