populateBean方法执行后,就开始执行initializeBean方法了。在这之前前面已经完成了Bean的属性设置、依赖注入,这里属于bean初始化过程的后置部分。给用户提供一个入口,实现其他特性。
方法源码如下所示:
// AbstractAutowireCapableBeanFactory protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { // JDK安全校验机制 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; // bean后置处理器的postProcessBeforeInitialization方法 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); } // bean后置处理器的postProcessAfterInitialization方法 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
如上代码所示,这里主要核心有四个步骤:invokeAwareMethods、applyBeanPostProcessorsBeforeInitialization、invokeInitMethods以及applyBeanPostProcessorsAfterInitialization。① invokeAwareMethods方法
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) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
源码如上所示,其将会分别尝试触发:
((BeanNameAware) bean).setBeanName(beanName);-设置BeanName
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);–设置Bean加载器
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);–设置BeanFactory
② applyBeanPostProcessorsBeforeInitialization
applyBeanPostProcessorsBeforeInitialization方法会循环遍历BeanPostProcessor并调用其postProcessBeforeInitialization方法。
如CommonAnnotationBeanPostProcessor其继承自InitDestroyAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor接口。那么在这里就会反射调用那些被标注了@PostConstruct注解的方法,也可以看到其是在init-method方法执行前。③ invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // 是否为InitializingBean,也就是是否实现了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 + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 调用其afterPropertiesSet方法 ((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)) { // 尝试反射调用initMethod 初始化方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
也就是说invokeInitMethods方法将会分别尝试触发:
- ((InitializingBean) bean).afterPropertiesSet();
- invokeCustomInitMethod(beanName, bean, mbd);
④ applyBeanPostProcessorsAfterInitialization
该方法会循环遍历BeanPostProcessor
并调用其postProcessAfterInitialization
方法。
同样以CommonAnnotationBeanPostProcessor为例,这里会触发其postProcessAfterInitialization调用,不过该处理器此时未做任何动作只是返回了bean。
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
总结
在调用Bean的初始化方法之前,会调用一系列的aware接口实现,把相关的BeanName、BeanClassLoader以及BeanFactory注入到Bean中区。
接着会看到对invokeInitMethods的调用,如果Bean实现了InitializingBean的接口,会调用其afterPropertiesSet方法。
最后还会判断Bean是否配置有initMethod,如果有那么通过invokeCustomInitMethod方法 来直接调用,最终完成Bean的初始化。
关于Bean的初始化/生命周期可以参考博文:
Spring中Bean的作用域与生命周期
Spring中bean的初始化和销毁几种实现方式详解
Spring中那些BeanPostProcessor在Bean实例化过程中的作用