SpringIoc源碼(二十)- BeanFactory(九)- getBean(doCreateBean - initializeBean生命週期回調)

目錄

1、Aware接口回調

2、BeanPostProcessor的postProcessBeforeInitialization方法回調

3、ApplicationContextAwareProcessor的postProcessBeforeInitialization

4、InitializingBean的afterPropertiesSet回調;自定義init方法回調

1)、回調InitializingBean的afterPropertiesSet方法

2)、自定義init方法回調

5、BeanPostProcessor的postProcessAfterInitialization方法回調

總結Bean的生命週期


    initializeBean方法就是Bean的生命週期過程,可以參照Spring-Bean的作用域和生命週期。從下面的步驟可以大致分爲4步驟進行回調。

protected Object initializeBean(final String beanName, final Object bean,
    @Nullable RootBeanDefinition mbd) {
    // 回調Bean實現的Aware相關接口
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    // 回調BeanPostProcessor的before接口
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    // 回調init接口
    invokeInitMethods(beanName, wrappedBean, mbd);
    // 回調BeanPostProcessor的after接口
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
}

1、Aware接口回調

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);
        }
    }
}
  1. 如果Bean實現了BeanNameAware接口,則在此處回調setBeanName方法
  2. 如果Bean實現了BeanClassLoaderAware接口,則在此處回調setBeanClassLoader方法
  3. 如果實現了BeanFactoryAware接口,則在此處回調setBeanFactory方法

 

2、BeanPostProcessor的postProcessBeforeInitialization方法回調

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        // 如果前置回調方法中修改了Bean,則返回修改後的Bean
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

    遍歷所有的BeanPostProcessor,回調postProcessBeforeInitialization前置方法,該方法中允許對Bean進行修改。其中有個比較特殊的ApplicationContextAwareProcessor,並且爲列表的第一個被回調。

 

3、ApplicationContextAwareProcessor的postProcessBeforeInitialization

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
        return bean;
    }

    // 省略權限檢查部分的代碼
    invokeAwareInterfaces(bean);
    return bean;
}

    如果Bean沒有實現以上接口則直接返回,否則就進行回調:

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}
  1. 如果Bean實現了EnvironmentAware接口,則在此處回調setEnvironment方法
  2. 如果Bean實現了EmbeddedValueResolverAware接口,則在此處回調setEmbeddedValueResolver方法
  3. 如果實現了ResourceLoaderAware接口,則在此處回調setResourceLoader方法
  4. 如果實現了ApplicationEventPublisherAware接口,則在此處回調setApplicationEventPublisher方法
  5. 如果實現了MessageSourceAware接口,則在此處回調setMessageSource方法
  6. 如果實現了ApplicationContextAware接口,則在此處回調setApplicationContext方法

 

4、InitializingBean的afterPropertiesSet回調;自定義init方法回調

protected void invokeInitMethods(String beanName, final Object bean, 
    @Nullable RootBeanDefinition mbd) throws Throwable {
    // 回調InitializingBean的afterPropertiesSet方法
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        // 省略部分代碼
        ((InitializingBean) bean).afterPropertiesSet();
    }
    // 回調自定義的init方法
    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);
        }
    }
}

1)、回調InitializingBean的afterPropertiesSet方法

    如果Bean實現了InitializingBean接口,則在此處回調afterPropertiesSet方法。

2)、自定義init方法回調

    如果Spring xml配置中的<bean />標籤設置了init-method屬性,或者在Bean的方法上添加@PostConstruct註解,則在該出回調自定義的初始化方法。解析完成後定義的方法名稱被存儲爲BeanDefinition的initMethodName字段中。回調過程如下:

protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
        throws Throwable {
    // 獲取自定義名稱,不能爲空
    String initMethodName = mbd.getInitMethodName();
    Assert.state(initMethodName != null, "No init method set");
    // 根據方法是否爲Public,獲取反射的Method
    Method initMethod = (mbd.isNonPublicAccessAllowed() ?
            BeanUtils.findMethod(bean.getClass(), initMethodName) :
            ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
    // 檢查是否一定要進行回調
    if (initMethod == null) {
        if (mbd.isEnforceInitMethod()) {
            throw new BeanDefinitionValidationException("Could not find an init method named '" +
                    initMethodName + "' on bean with name '" + beanName + "'");
        }
        else {
            // Ignore non-existent default lifecycle methods.
            return;
        }
    }

    // 當前定義的可能只是接口,則獲取真是的方法
    Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
    // 如果是非public則強制破解,反射回調方法
    ReflectionUtils.makeAccessible(methodToInvoke);
    methodToInvoke.invoke(bean);
}

 

5、BeanPostProcessor的postProcessAfterInitialization方法回調

@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;
}

    歷所有的BeanPostProcessor,回調postProcessAfterInitialization後置方法,這也是Aop實現的根本。現在拿到的Bean是已經不需要再進行修改的了,則在該出根據對象本身,創建代理對象,返回代理對象,進行使用。

    在最外層,會將實現了DisposableBean的以適配器添加到銷燬容器中,到時候進行回調。就完成了Bean的整個生命週期。

 

總結Bean的生命週期

1、BeanNameAware#setBeanName方法

2、BeanClassLoaderAware#setBeanClassLoader方法

3、BeanFactoryAware#setBeanFactory方法

4、EnvironmentAware#setEnvironment方法

5、EmbeddedValueResolverAware#setEmbeddedValueResolver方法

6、ResourceLoaderAware#setResourceLoader方法

7、ApplicationEventPublisherAware#setApplicationEventPublisher方法

8、MessageSourceAware#setMessageSource方法

9、ApplicationContextAware#setApplicationContext方法

10、其他BeanPostProcess#postProcessBeforeInitialization方法

11、InitializingBean#afterPropertiesSet方法

12、init-method或者@PostConstruct定義的方法

13、BeanPostProcess#postProcessAfterInitialization方法

 

14、正常Bean使用階段

15、註冊DisposableBean#destroy方法的回調

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章