7、Spring之Bean生命周期~初始化
7、Spring之Bean生命周期~初始化
- 初始化
- invokeAwareMethods()方法
- applyBeanPostProcessorsBeforeInitialization()方法
- invokeInitMethods()方法
- applyBeanPostProcessorsAfterInitialization()方法
初始化
spring初始化分为三步:初始化前、初始化和初始化后,每一步作用也不相同,废话不多说,上代码:
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
*
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
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()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 初始化
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 初始化后 AOP
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
通过上述代码,我们可以看到:
- 初始化方法的第一步会先调用invokeAwareMethods()方法进行Aware回调;
- 调用applyBeanPostProcessorsBeforeInitialization()方法完成初始化前操作;
- 调用invokeInitMethods()方法完成初始化操作;
- 调用applyBeanPostProcessorsAfterInitialization()方法完成初始化后操作;
invokeAwareMethods()方法
invokeAwareMethods()方法详解
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// beanName回调
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// BeanClassLoader回调
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//BeanFactory回调
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
通过上述代码我们可以看到,这里会对BeanNameAware、BeanClassLoaderAware和BeanFactoryAware三个Aware接口进行回调操作;
回调initializeBean()方法
applyBeanPostProcessorsBeforeInitialization()方法
applyBeanPostProcessorsBeforeInitialization()方法详解
@Override
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;
}
这里我们可以看到,如果Bean有设置BeanPostProcessor接口的postProcessBeforeInitialization()方法在这里进行调用,Spring在这一步会判断bean对象有没有加@PostConstruct和@PreDestroy,如果有赋值给对应的属性,方便后续直接调用;
回到initializeBean()方法
invokeInitMethods()方法
invokeInitMethods()方法详解
/**
* Give a bean a chance to react now all its properties are set,
* and a chance to know about its owning bean factory (this object).
* This means checking whether the bean implements InitializingBean or defines
* a custom init method, and invoking the necessary callback(s) if it does.
*
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the merged bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @throws Throwable if thrown by init methods or by the invocation process
* @see #invokeCustomInitMethod
*/
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
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();
}
}
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);
}
}
}
这里可以看到,首先会判断当前Bean对象是否实现了InitializingBean接口,如果实现了就调用它的afterPropertiesSet()方法,然后判断BeanDefinition中是否指定初始化方法,如果指定啦初始化方法且不是afterPropertiesSet()方法的话,会调用BeanDefinition指定的初始化方法;
回到initializeBean()方法
applyBeanPostProcessorsAfterInitialization()方法
applyBeanPostProcessorsAfterInitialization()方法详解
@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对象实现了BeanPostProcessor接口的postProcessAfterInitialization()方法进行初始化后设置,Spring中的AOP就是基于初始化后 实现的,初始化后返回的对象才是最终的Bean对象。
回到initializeBean()方法