主要流程
到这里,bean生命周期已经完成了两件大事:
- 调用 createBeanInstance() 方法:完成 bean 的实例化工作
 - 调用 populateBean() 方法:完成 bean 的属性填充注入工作
 
接下来是第三件大事:
初始化 Bean,主要工作:调用工厂回调、init方法执行、后置处理器的执行。
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 {// 对特殊的 bean 处理:Aware、 BeanClassLoaderaware、 BeanFactoryAwareinvokeAwareMethods(beanName, bean);}// 执行前置处理器Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// 执行自定义init方法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;}
流程1 - invokeAwareMethods�
实现 Aware 接口用于让 bean 能拥有某些额外的扩展能力。
- 如果 bean 实现了 BeanNameAware 接口,则将 beanName 设置进去
 - 如果 bean 实现了 BeanClassLoaderAware 接口,则将 ClassLoader 设置进去
 - 如果 bean 实现了 BeanFactoryAware 接口,则将 beanFactory 设置进去
 
也就是说实现了上面的接口,就能得到相关的资源。代码如下所示:
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);}}}
流程2 - applyBeanPostProcessorsBeforeInitialization
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;}
postProcessBeforeInitialization() 方法是 BeanPostProcessor 接口提供的方法。
它是在 bean 初始化之前调用的,这时的 bean 已完成了实例化和属性填充注入工作。
🔥 流程3 - invokeInitMethods�
执行自定义init方法。自定义方法的方式:
- bean 在 xml 文件中配置 init-method ;
 - 标签或使用注解 @Bean(initMethod=” “) ;
 实现 InitializingBean 接口,并且在 afterPropertiesSet() 方法中实现自己初始化的业务逻辑。
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);}}}
流程4 - applyBeanPostProcessorsAfterInitialization�
postProcessAfterInitialization() 方法是 BeanPostProcessor 接口提供的方法,可以看到它是在 bean 初始化之后调用的,这时的 bean 已完成了实例化,属性填充注入,初始化的工作;可以认为是一个完整的 bean 已在 spring 容器中。
如果使用了 spring aop 功能,那么代理对象的产生就在这个 applyBeanPostProcessorsAfterInitialization() 方法中。Spring 初始化 bean 的方式小结
- xml 配置文件中指定 init-method 标签
 - 使用 @PostConstruct 注解
 - 实现 InitializingBean 接口
 - 使用 @Bean(initMethod=” “) 注解指定
 
