摘要:上文解析了AnnotationAwareAspectJAutoProxyCreator的注册过程,但是我们却并没有分析注册它有何用?能在实现AOP功能的过程中起到什么作用,今天我就会详细分析!
一.注册AnnotationAwareAspectJAutoProxyCreator的原因
首先让我们先看下此类的继承和实现关系,我用的idea构建的。
不难看出,此类间接实现了BeanPostProcessor,那么此类也就拥有了拦截功能。话题从此处展开,先来解释下BeanPostProcessor的作用,那么真相自然而然便会浮出水面。
二.BeanPostProcessor的作用
请先看Spring官网的原话,看它是如何解释的。
有道翻译了一下,它说BeanPostProcessor算是一个容器的扩展点,对应AOP代理是必不可少的。所有说注册此Bean是必不可少的一步。那它在AOP代理中,主要做了什么事呢?我们先看下BeanPostProcessor的结构。
/** *工厂挂钩,允许自定义修改新的bean实例,例如:检查标记接口或用代理包装它们。 *ApplicationContexts可以自动检测BeanPostProcessor中的bean,并将它们应用于随后创建的任何bean **/ public interface BeanPostProcessor { //为在Bean的初始化前提供回调入口 @Nullable default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /** *在任何bean 之后,将这个BeanPostProcessor应用到给定的新bean实例 *初始化回调(比如InitializingBean的{@code afterPropertiesSet}) *或自定义init-方法)。bean已经被填充了属性值。 *返回的bean实例可能是原始bean的包装器。 **/ @Nullable default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } }
该类的功能为:通过在postProcessBeforeInitialization和postProcessAfterInitialization对传入的bean进行行为的自定义修改。这两个方法在什么时候会被调用到呢?类的注释说明的很清楚,ApplicationContext会自动检测BeanPostProcessor中的bean,并将它们应用于随后创建的bean。换句话说,在bean创建的过程中,这些扩展点会被调用。而在Spring创建bean的过程中,确实有这么一个调用过程,那就是AbstractAutowireCapableBeanFactory类中的initializeBean方法。
此处分别调用了BeanPostProcessor类中的beforeXXX和afterXXX。然后注入到IOC容器中。
//调用BeanPostProcessor后置处理器实例对象初始化之前的处理方法 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //调用Bean实例所有的后置处理中的初始化前处理方法,为Bean实例对象在 //初始化之前做一些自定义的处理操作 Object current = beanProcessor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; } //调用BeanPostProcessor后置处理器实例对象初始化之后的处理方法 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //遍历容器为所创建的Bean添加的所有BeanPostProcessor后置处理器 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //调用Bean实例所有的后置处理中的初始化后处理方法,为Bean实例对象在 //初始化之后做一些自定义的处理操作 Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
那这个地方的BeanPostProcessor从哪来的呢?又是何时被创建的?
三.BeanPostProcessor实例何时被创建
先看看上面的getBeanPostProcessors()方法,到底做了什么?
public List<BeanPostProcessor> getBeanPostProcessors() { return this.beanPostProcessors; } /** BeanPostProcessors to apply in createBean. */ private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
这是直接取的成员变量的值,那难免好奇,这个list又是在哪初始化的呢?如果熟悉IOC容器初始化的同学应该都知道,BeanPostProcessor的初始化工作是在这里完成的。让我们一起看看源码。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // 在此处完成向IOC容器注册BeanPostProcessor registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
这段代码在AbstractApplicationContext中,逻辑是非常清晰的,基本能看出来Spring是如何去完成IOC容器的初始化工作的。今天我们只关心后置处理器的初始化,其他的以后在单独写博客分析。让我们进入registerBeanPostProcessors(beanFactory)方法看看里面的逻辑。
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //根据类型获取到所有的BeanPostProcessor 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)); // 区分并排序所有的BeanPostProcessor 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); } } // 先排序,然后再注册到IOC容器中 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); }
首先根据类型获取到所有的BeanPostProcessor,这一步早在扫描类路径的时候就已经拿到了所以需要被Spring托管的beanName。
从这里我们可以看到,拿到了4个beanName,这几个都是Spring内部的。这就包含了我们最开始创建的自动代理创建器。
private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { for (BeanPostProcessor postProcessor : postProcessors) { //此时开始添加 beanFactory.addBeanPostProcessor(postProcessor); } }
将这些后置处理器分别进行分类后排序,然后加入IOC容器中。
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { //先移除,防止重复添加 this.beanPostProcessors.remove(beanPostProcessor); // Track whether it is instantiation/destruction aware if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { this.hasInstantiationAwareBeanPostProcessors = true; } if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { this.hasDestructionAwareBeanPostProcessors = true; } //此处将创建好的bean对象,加入list中,完成初始化工作 this.beanPostProcessors.add(beanPostProcessor); }
这里逻辑也比较简单,如果存在则先移除,然后再加入当前的list中。至此,list已经初始化完成。
总结
这一章节,带领大家揭开了注册AnnotationAwareAspectJAutoProxyCreator的原因,正因为当前这个类间接实现了BeanPostProcessor接口,那么它就具备了拦截器的功能,就能在bean创建的过程中对其进行增强,这也就为动态织入代码提供了可能性。下一篇文章,我会开始分析Spring是如何利用该类对象来为目标对象生成代理对象的。