关于spring:Spring-Framework源码解析BeanPostProcessor讲解

6次阅读

共计 10708 个字符,预计需要花费 27 分钟才能阅读完成。

Spring Framework 版本 5.3.4

1. BeanPostProcessor 是干什么的?

BeanPostProcessor 接口作用是:如果咱们须要在 Spring 容器实现 Bean 的实例化、配置和其余的初始化前后增加一些本人的逻辑解决,咱们就能够定义一个或者多个 BeanPostProcessor 接口的实现,而后注册到容器中。(相似于拦截器和过滤器)。BeanPostProcessor 分为三大类如下图:

  • 实例化
  • 初始化
  • 销毁

Bean 实例化会执行 InstantiationAwareBeanPostProcessorSmartInstantiationAwareBeanPostProcessor 这两类处理器,Bean 实例化后每个 bean 就会通过 BeanPostProcessorMergedBeanDefinitionPostProcessor 实现的类的解决。Bean 销毁会通过 DestructionAwareBeanPostProcessor 处理器。

Spring Bean 的实例化图解:

在查看完 Aware 接口后,就开始调用 BeanPostProcessor 进行前置解决后置解决。上面来看一下 Spring 中的几类继承:

  • AOP 相干的

  • bean 和 context 相干的

  • Spring Boot 相干的实现

BeanPostProcessor 是在 Bean 实例化后,在自定义初始化办法前后执行。

2. BeanPostProcessor

处理器定义了 Bean 初始化 前后执行的办法。

public interface BeanPostProcessor {
​
    // 自定义初始化办法之前执行
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}
​
    // 自定义初始化办法之后执行
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
​
}

代码示例地址:github.com/mxsm/spring…

代码演示:

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
​
        System.out.println("----before-----" + beanName);
​
        return bean;
    }
​
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
​
        System.out.println("----after-----" + beanName);
​
        return bean;
    }
}
public class TestBean {
​
    private String name;
​
    public void init(){System.out.println("TestBean---init()");
        this.name = "test";
    }
​
    public String getName() {return name;}
​
    public void setName(String name) {this.name = name;}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
​
    <bean id="testBean" class="com.github.mxsm.bean.TestBean" init-method="init"/>
​
    <bean class="com.github.mxsm.processor.MyBeanPostProcessor" id="myBeanPostProcessor"/>
​
</beans>
public class ApplicationBoot{public static void main( String[] args ) {
​
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
        TestBean testBean = applicationContext.getBean(TestBean.class);
        System.out.println(testBean.getName());
​
    }
}


通过代码能够看进去执行的后果。

3.InstantiationAwareBeanPostProcessor

该处理器定义了 Bean 实例化 前后执行的办法。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    // 实例化之前
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { 
        // 这里能够自定义代理类
        return null;
    }
​
    // 实例化后 - 然而执行在初始化之前
    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}
​
    // 解决 bean 的 Properties 值
    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
            throws BeansException {
​
        return null;
    }
​
}

4.DestructionAwareBeanPostProcessor

该处理器了销毁 Bean 之前的操作。

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
​
    //bean 销毁之前
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
​
    //bean 是否须要销毁
    default boolean requiresDestruction(Object bean) {return true;}
​
}
​

5. 看一下 Spring 本身的实现

class ApplicationContextAwareProcessor implements BeanPostProcessor {
​
    private final ConfigurableApplicationContext applicationContext;
​
    private final StringValueResolver embeddedValueResolver;
​
​
    /**
     * Create a new ApplicationContextAwareProcessor for the given context.
     */
    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }
​
​
    @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;
    }
​
    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);
            }
        }
    }
​
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
​
}

以后次要用来解决继承了 Aware 接口类。而后依据 Aware 接口的不同实现设置对应的接口对象

6. BeanPostProcessor Spring 源码剖析

首先明确一点 BeanPostProcessor 实现的类都是 Spring 容器中的一个 Bean。在 AbstractApplicationContext#refresh 是最重要的一个办法:

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
                // 省了局部代码
​
            try {

                // 省了局部代码
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
​
              // 省了局部代码
            }
​
            catch (BeansException ex) { }
​
            finally {// 省了局部代码}
        }
}
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 通过 PostProcessorRegistrationDelegate 类的静态方法解决
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

上面看一下 PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); 办法

    public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
​
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
​
        // Register BeanPostProcessorChecker that logs an info message when
        // a bean is created during BeanPostProcessor instantiation, i.e. when
        // a bean is not eligible for getting processed by all BeanPostProcessors.
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
​
        // 解决分为三类:1 PriorityOrdered 实现 2 Ordered 第三类就是一般的
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
        List<String> orderedPostProcessorNames = new ArrayList<>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<>();
        for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);
                }
            }
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);
            }
            else {nonOrderedPostProcessorNames.add(ppName);
            }
        }
​
        // 解决 PriorityOrdered 实现
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
​
        // 解决 Ordered 实现.
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);
            }
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);
​
        // 解决失常的
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
​
        // 注册 MergedBeanDefinitionPostProcessor
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);
​
        // Re-register post-processor for detecting inner beans as ApplicationListeners,
        // moving it to the end of the processor chain (for picking up proxies etc).
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

通过该办法将 BeanPostProcessor 的以上几种实现类都注册到 Spring 中。

而后在生成 Bean 的时候去执行,AbstractAutowireCapableBeanFactory.createBean 创立 Bean

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

            // 省略代码

            try {
            // 执行实例化之前办法.
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {return bean;}          
            // 省略代码    
        }
    }
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {// 执行 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation( 实例化之前办法)
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {// 执行 InstantiationAwareBeanPostProcessor#postProcessAfterInitialization( 初始化后的办法)
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

通过代码能够晓得 resolveBeforeInstantiation 办法是执行实例化之前的办法。如果实例化之前的办法返回了对应 Bean 那么间接执行初始化后的办法。实例化 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 办法执行返回 Bean 为空就调用 AbstractAutowireCapableBeanFactory#doCreateBean 办法。在这个办法外面有如下几个重要的办法:

  • AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors 办法
  • 执行 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 办法
  • AbstractAutowireCapableBeanFactory#populateBean 办法
  • 执行 InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation 办法,如果后面办法返回 true,执行办法 InstantiationAwareBeanPostProcessor#postProcessProperties 办法
  • AbstractAutowireCapableBeanFactory#initializeBean 办法
  • 执行 BeanPostProcessor#postProcessBeforeInitialization 办法,而后执行 AbstractAutowireCapableBeanFactory#invokeInitMethods 办法 (包含实现了 InitializingBean 接口的办法或者有注解 @PostConstruct 的办法),而后执行 BeanPostProcessor#postProcessAfterInitialization

7. 总结

BeanPostProcessor 次要用来解决 Bean 外部的注解。比方 Spring 本人实现的 @Autowired、@Value,@EJB,@WebServiceRef,@PostConstruct,@PreDestroy 等

自定义相似于 @Value,@Autowired 的注解,次要用于 Java 类变量或者办法上的注解 次要用于解决 Bean 外部的注解实现,次要是变量或者办法下面的注解

正文完
 0