SpringIoC依赖注入的过程(六)
前几篇文章详细地解读了Spring的依赖注入的过程,触发依赖注入的是getBean方法,依赖注入发生的地方是populateBean方法,而获取依赖bean的实例还是通过getBean方法。截止到上文已经解读完populateBean的全部逻辑,本文介绍下,依赖注入之后bean的初始化操作。回到AbstractAutowireCapableBeanFactory的doCreateBean方法,populateBean方法之后紧接着是initializeBean,它的源码如下
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
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);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
第一步先调用各种aware接口的相关set方法,将相关的信息设置到bean中。这里被设置的对象可以有三个,分别是beanName、beanClassLoader以及beanFactory,如下代码:
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) {
((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
向bean中设置完beanFactory等信息之后,就是通过applyBeanPostProcessorsBeforeInitialization方法在初始化bean之前调用相关的后置处理器做一些事情。那么各种后置处理器都做了什么呢?我们看一下几个重要的后置处理的postProcessBeforeInitialization方法。在ApplicationContextAwareProcessor中,该方法调用实现了上下文相关的aware接口(ApplicationContextAware、ResourceLoaderAware等)的set方法,将上下文相关信息设置到bean中,具体的代码就不在这里粘了。InitDestroyAnnotationBeanPostProcessor中调用
PostConstruct方法,代码如下:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
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, "Couldn't invoke init method", ex);
}
return bean;
}
还记得
SpringIoC依赖注入的过程(二)中,后置处理器通过postProcessMergedBeanDefinition找到
PostConstruct方法,这里就是对其进行了调用。
初始化过程在调用过每个后置处理器的postProcessBeforeInitialization后置处理器之后,通过invokeInitMethods继续执行剩余的初始化动作。
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
这里会执行两类初始化方法,一个是实现
InitializingBean接口而实现其中的afterPropertiesSet方法,还有就是我们在BeanDefinition中自己指定的初始化方法(即在配置文件中声明的init-method)。若bean实现了InitializingBean就回调其
afterPropertiesSet方法;然后通过反射调用
init-method。初始化的最后任务就是在bean初始化方法执行完毕之后再次调用bean的后置处理器,这次调用它们的postProcessAfterInitialization方法。
好啦,现在我们得到bean是一个实例化好的、依赖注入过得并且初始化后的对象。而bean的依赖注入过程也就全部结束了。