上一篇分析了单实例bean创建过程中的属性赋值,接下来我们分析,单实例bean属性赋值之后的初始化
**initializeBean()**。
1. initializeBean()
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {/*检查当前bean是否实现了aware接口,再具体判断实现的哪个aware接口,做一些赋能操作。*/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()) {/*初始化后的后置处理器执行点*//*典型应用:AOP的具体实现*/wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
在初始化之前,把当前bean实现的所有Aware接口都执行一遍。**invokeAwareMethods()**
在初始化之前,调用后置处理器。**applyBeanPostProcessorsBeforeInitialization()**
执行初始化逻辑。**invokeInitMethods()**
执行后置处理器的调用点,典型的实现其实就是AOP。**applyBeanPostProcessorsAfterInitialization()**
返回包装对象。
2.invokeAwareMethods()
private void invokeAwareMethods(String beanName, 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);}}}
3.applyBeanPostProcessorsBeforeInitialization()
@Overridepublic Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;/*beanPostProcessor的执行逻辑*/for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName);if (current == null) {return result;}result = current;}return result;}
循环所有的后置处理器,执行前置方法,如果有一个返回结果为空,直接短路,后面的都不执行了。
4.invokeInitMethods()
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {/*如果是实现了InitializingBean接口*/boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}/*执行afterPropertiesSet方法*/((InitializingBean) bean).afterPropertiesSet();}if (mbd != null && bean.getClass() != NullBean.class) {/*判断重写init方法没?*/String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {/*执行重写的init方法*/invokeCustomInitMethod(beanName, bean, mbd);}}}
判断实现了**InitializingBean**接口的,执行里面的方法。
判断重写了初始化方法的,执行重写的方法。
4.1 invokeCustomInitMethod()
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)throws Throwable {/*从bd获取init方法*/String initMethodName = mbd.getInitMethodName();Assert.state(initMethodName != null, "No init method set");/** isNonPublicAccessAllowed 非公开访问** 这里完成之后就会获取到通过init方法定义的方法对象。* */Method initMethod = (mbd.isNonPublicAccessAllowed() ?BeanUtils.findMethod(bean.getClass(), initMethodName) :ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));/*如果init方法为空*/if (initMethod == null) {if (mbd.isEnforceInitMethod()) {throw new BeanDefinitionValidationException("Could not find an init method named '" +initMethodName + "' on bean with name '" + beanName + "'");}else {if (logger.isTraceEnabled()) {logger.trace("No default init method named '" + initMethodName +"' found on bean with name '" + beanName + "'");}// Ignore non-existent default lifecycle methods.return;}}if (logger.isTraceEnabled()) {logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");}/*将init方法转换成接口层面获取的initMethod*/Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);try {/*反射执行方法*/ReflectionUtils.makeAccessible(methodToInvoke);methodToInvoke.invoke(bean);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}
5.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;
}
初始化之后,遍历所有的后置处理器,执行后置处理器的后置方法,如果有一个返回结果是空,直接返回,后面的后置处理器都不执行了。
至此,整个ioc容器的刷新流程就都分析完了,重点就在于单实例bean的创建流程,首先会去**getBean() doGetBean() getSinglton() createBean() doCreateBean() populateBean() initializeBean()**。下一篇我们将会去分析Spring的三级缓存和循环依赖。
