从BeanFactory源码看Bean的生命周期( 六 )

没啥好解释的,实际上InstantiationAwareBeanPostProcessor的过程和它差不多,并且比它复杂 。
init-method的调用#// 调用before初始化Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 调用init-methodinvokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}那么我们来查看invokeInitMethods方法:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {// 该Bean是否是initializingBean的实例boolean isInitializingBean = (bean instanceof InitializingBean);// 如果是 , 并且有`afterPropertiesSet`方法if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {// 调用afterPropertiesSet方法((InitializingBean) bean).afterPropertiesSet();}if (mbd != null && bean.getClass() != NullBean.class) {// 获取init-method名字String initMethodName = mbd.getInitMethodName();// 如果`initMethodName`不是空并且`initMethodName`并不和`afterPropertiesSet`同名且不是InitalizingBean(防止重复调用) , 并且Bean中实际有这个方法if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {// 调用initmethodinvokeCustomInitMethod(beanName, bean, mbd);}}}所以,BeanFactory先是对于实现了InitializingBean的Bean的afterPropertiesSet进行调用,然后再对用户指定的init-method进行调用 。
InitializingBean实战#@Datapublic class Workbench implements InitializingBean {@Autowiredprivate Person operator;@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet");}}结果:
afterPropertiesSetWorkbench(operator=Person(name=Yudoge))init-method实战#添加init方法
@Datapublic class Workbench implements InitializingBean {@Autowiredprivate Person operator;@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet");}public void init() {System.out.println("init");}}BeanDefinition中设置init方法名
// 设置Init方法名workbenchRbd.setInitMethodName("init");结果
afterPropertiesSetinitWorkbench(operator=Person(name=Yudoge))关于@PostConstruct#貌似BeanFactory并不支持@PostConstruct,它好像是ApplicationContext通过预注册InstantiationAwareBeanPostProcessor实现的 。这是我猜的 。
BeanPostProcessor.post初始化#略 , 因为前面已经讲了够多了 , 猜也能猜到怎么实现的
初始化阶段总结#

  1. 调用Aware方法
  2. 调用BeanPostProcessor的before初始化
  3. 如果是InitializingBean,调用afterPropertiesSet方法
  4. 如果有init-method,调用
  5. 调用BeanPostProcessor的after初始化
尾声:Bean的销毁阶段#
从BeanFactory源码看Bean的生命周期

文章插图
回到doCreateBean方法中,最后,该方法判断了 , 如果必要的话就将该Bean注册到DisposableBean中:
try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {}我猜其中的逻辑就是看看该Bean是不是DisposableBean的实例,如果是 , 注册到一个什么表中,方便销毁Bean时调用它的destory方法 。
我们先不管,先看BeanFactory中有没有什么destroyBean这种方法 。果然,在ConfigurableBeanFactory中定义了这个方法 , AbstractBeanFactory把它实现了:
@Overridepublic void destroyBean(String beanName, Object beanInstance) {destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));}protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();}这里创建了一个什么DisposableBeanAdapter,然后调用了destroy方法,就没干别的了 。
DisposableBeanAdapter#DisposableBeanAdapter的描述如下:
/** * 实现了`DisposableBean`和`Runnable`的Adapter,对给定的Bean执行多个销毁步骤: * *- DestructionAwareBeanPostProcessors; *- 本身就实现了DisposableBean的Bean *- BeanDefinition中定义的Bean销毁方法 */class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable

推荐阅读