SpringSpring

[Spring]影响Spring Bean生命周期的BeanPo

2021-03-06  本文已影响0人  AbstractCulture

前言

Spring中使用了许多BeanPostPorcessor来处理回调,在了解Spring Bean的生命周期时,会发现充斥着许多BeanPostProcessor的方法执行.了解这些Spring框架的BeanPostProcessor,来试图找到一些AOP有关的线索.
从整体的视角来看,Spring IoC支持以注解驱动的方式来创建与管理对象,那么Spring AOP是用来代理对象的,没有了对象,空谈Spring AOP是无意义的。在前面分析getBean的流程中,我们也找到了一些AOP的蛛丝马迹,下面我们从BeanPostcessor的角度来看看在Bean的生命周期中一些关键的后置处理器.

UML

UML

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor是BeanPostProcessor的子接口,主要是用于Spring框架内部使用,它有3个回调方法,通常用于抑制特定目标Bean的默认实例化,例如,创建具有特殊TargetSource的代理(池目标,延迟初始化目标等),或实施其他注入策略,例如字段注入:

在实例化目标bean(doCreateBean)之前应用此BeanPostProcessor。返回的Bean对象可以是代替目标Bean使用的代理,从而有效地抑制了目标Bean的默认实例化。
如果此方法返回一个非null对象,则bean创建过程将被短路。可以应用自已配置BeanPostProcessors的postProcessAfterInitialization回调来进一步处理。

通过构造函数或工厂方法在实例化bean之后但在发生Spring属性填充(通过显式属性或自动装配)之前执行操作。
这是在Spring的自动装配开始之前对给定的bean实例执行自定义字段注入的理想回调。
默认实现返回true。

在beanFactory将其作为getBean的返回值前,对给定的属性值(比如被Spring框架的注解标注的成员)进行后处理,无需使用属性描述符(property descriptors)。
这个关键的方法便是populateBean中的@Autowired注解解析入口.

SmartInstantiationAwareBeanPostProcessor

Spring框架内部使用的专用接口,扩展了InstantiationAwareBeanPostProcessor接口,在整个Spring Bean的生命周期中,会经常与该接口打交道。

  1. predictBeanType:
    预测从此处理器的postProcessBeforeInstantiation回调最终返回的bean的类型。
    默认实现返回null。
    Bean在经过postProcessBeforeInstantiation处理后也许返回了代理类,那么此处即提前声明好代理后的对象类型.
  2. determineCandidateConstructors
    声明给定bean所要应用的候选构造函数。
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors中使用了该方法用于Bean的实例化过程中推断构造函数,如果能从SmartInstantiationAwareBeanPostProcessor中获取到构造函数数组,那么直接使用该构造函数数组进行对象实例化.
  3. getEarlyBeanReference
    提前暴露引用,用于解决循环依赖问题.

MergedBeanDefinitionPostProcessor

AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor都实现了此接口,用于查找被Spring所支持的注解所标记的元数据. 在doCreateBean中,会调用applyMergedBeanDefinitionPostProcessors对此后置处理器进行统一激活.
下面贴一下经典的案例:

    @Override
    /**
     * InjectionMetadata-内部类,用于管理注入元数据。不适用于直接在应用程序中使用。
     */
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        // 扫描当前Class是否有被@Autowired、@Value标记的成员变量,最终封装到InjectionMetadata中
        InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
        // 将Spring容器需要用默认策略注入的 element 保存到 checkedElements 中
        metadata.checkConfigMembers(beanDefinition);
    }

ApplicationContextAwareProcessor

主要用于处理实现了Aware接口的回调.重写了BeanPostProcessorpostProcessBeforeInitialization方法.在AbstractAutowireCapableBeanFactory#initializeBean中,工厂会先执行invokeAwareMethods来激活BeanNameAwareBeanClassLoaderAwareBeanFactoryAware,其他的Aware接口交由此后置处理器进行激活.

    @Override
    @Nullable
    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;

        if (System.getSecurityManager() != null &&
                (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                        bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                        bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }
    
    // 激活实现了Aware的接口: EnvironmentAware、EmbeddedValueResolverAware  
    // ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware  
    // ApplicationContextAware
    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            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);
            }
        }
    }

DestructionAwareBeanPostProcessor

在销毁Bean前执行Bean所声明的自定义销毁方法.
假设一个Bean实现了DisposableBean,那么在Spring Bean初始化的时候就会注册销毁方法,在Spring对Bean进行销毁的时候,通过此后置处理器进行统一激活。

流程图

以下是今天文章所讲的BeanPostProcessor对Spring Bean生命周期的管理.

1 2
上一篇下一篇

猜你喜欢

热点阅读