1:写在前面
本文在spring通过不同的方式创建bean的基础上进行分析,作为补充,详细分析spring调用初始化方法的过程。
2:initializeBean
源码如下:
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// 安全模式和非安全模式最终都是通过调用方法invokeAwareMethods
// 来调用Aware的方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// <2021-03-29 15:38>
// 调用BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
// 对应的setXXX方法设置对应的信息
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// mdb不为null,且是自定义的bean
if (mbd == null || !mbd.isSynthetic()) {
// <2021-03-30 18:17>
// 调用bean的后置处理器的bean初始化前方法postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// <2021-03-30 18:18>
// 调用用户自定义的初始化方法
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()) {
// <2021-03-30 18:20>
// 调用bean的后置处理器的bean初始化后方法postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
<2021-03-29 15:38>
处参考2.1:invokeAwareMethods
。<2021-03-30 18:17>
,<2021-03-30 18:20>
处逻辑类似,是分别应用后置bean处理器初始化前和初始化后对应的方法,关于后置bean处理器可以参考这里。我们只看下<2021-03-30 18:17>
,是在调用用户自定义的初始化方法前,执行后置bean处理器的postProcessBeforeInitialization方法,源码如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
// 记录当前的bean
Object result = existingBean;
// 获取所有的后置bean处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 执行后置bean处理器的postProcessBeforeInitialization
// 方法获取用户处理后的对象
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 如果是用户处理后的对象为null,则直接返回上一个不为空
// 的处理器的执行结果(如果第一个就是返回null,则返回的是老bean)
if (current == null) {
return result;
}
// 将返回的新bean赋值到结果对象
result = current;
}
// 返回结果bean
return result;
}
<2021-03-30 18:18>
处主要是调用用户的初始化方法,具体参考2.2:invokeInitMethods
。
2.1:invokeAwareMethods
调用BeanNameAware,BeanFactoryAware,BeanClassLoaderAware对应的setXxx方法,源码如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
// 如果是Aware接口的子类
// 根据具体的不同子接口类型,调用不同的setXxx方法
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);
}
}
}
2.2:invokeInitMethods
源码如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// <2021-03-30 20:39>
boolean isInitializingBean = (bean instanceof InitializingBean);
// 如果是InitializingBean,则调用其afterPropertiesSet方法
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>) () -> {
// 调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用afterPropertiesSet方法
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
// 获取init-method定义的初始化方法
String initMethodName = mbd.getInitMethodName();
// 满足以下条件则调用init-method定义的初始化方法
// 1:有值 StringUtils.hasLength(initMethodName)
// 2:不是InitializingBean的子类或者是方法的名字不是afterPropertiesSet !(isInitializingBean && "afterPropertiesSet".equals(initMethodName))
// 3:!mbd.isExternallyManagedInitMethod(initMethodName),不知道判断什么
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用init-method定义的方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
<2021-03-30 20:39>
处是处理InitializingBean,这是一个接口,是spring留给我们的另外一个扩展点,作用是让用户能够在bean的属性都设置完毕后做一些操作,比如验证属性设置的正确与否等
,会调用其afterPropertiesSet
方法,该接口定义如下:
/**
* 当需要在所有属性都设置完毕后,执行一些操作的话,可以实现该接口
*/
public interface InitializingBean {
/**
当bean的所有属性设置完毕后,会调用该方法,可以在该方法内
做一些诸如属性验证的操作,当然也可以是在属性设置完毕后
才能执行的操作
*/
void afterPropertiesSet() throws Exception;
}
不是特别难,只需要让我们bean实现org.springframework.beans.factory.InitializingBean
接口就可以了。