• Spring AOP 自动代理创建器


    调试环境:https://gitee.com/jhxxb/MySpringBoot/tree/master/spring-base/Spring-AOP

    源码

    从 @EnableAspectJAutoProxy 注解开始

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class) // 给容器中导入了 AspectJAutoProxyRegistrar
    public @interface EnableAspectJAutoProxy {
        /**
         * 用 CGLIB 代理还是用 JDK 动态代理(需要实现接口),默认为 false,用 JDK 动态代理
         */
        boolean proxyTargetClass() default false;
    
        /**
         * 代理的暴露方式:解决内部调用不能使用代理的场景,默认为 false 表示不处理
         * true:这个代理就可以通过 AopContext.currentProxy() 获得这个代理对象的一个副本(ThreadLocal 里面),从而我们可以很方便得在 Spring 框架上下文中拿到当前代理对象(处理事务时很方便)
         * 必须为 true 才能调用 AopContext 的方法,否则报错:Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available.
         * @since 4.3.1
         */
        boolean exposeProxy() default false;
    }

    AspectJAutoProxyRegistrar

    这一步注入了一个 Bean:AnnotationAwareAspectJAutoProxyCreator,基于注解的自动代理创建器,应尽量避免自己创建 AutoProxyCreator,而是统一交给 Spring 来处理

    class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            // 这步非常重要,就是去注册了一个基于注解的 AspectJ 自动代理创建器(如果需要的话)
            AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
    
            AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
            if (enableAspectJAutoProxy != null) {
                // 若为 true,表示强制指定了要使用 CGLIB,那就强制告知到时候使用 CGLIB 的动态代理方式
                if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
                // 告知,强制暴露 Bean 的代理对象到 AopContext
                if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
        }
    }
    
    public abstract class AopConfigUtils {
        public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
        // findPriorityForClass 这个方法非常有意思:相当于找到 index 角标,然后
        // APC_PRIORITY_LIST 的内容是下面这几个,按照顺序排好的
        private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
    
        static {
            APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
            APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
            APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
        }
    
        @Nullable
        public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
            return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
        }
    
        @Nullable
        public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
            return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
        }
    
        @Nullable
        private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            // 很显然,这里如果我们自己定义了这样一个自动代理创建器,也是可以的
            if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
                BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
                // 如果我们自定义的并不是 cls 这个 class 类型的 Bean,那就做如下处理一下
                if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
                    // InfrastructureAdvisorAutoProxyCreator/AspectJAwareAdvisorAutoProxyCreator/AnnotationAwareAspectJAutoProxyCreator 的一个逻辑(防止用户注册错了,做一个容错处理)
                    int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
                    int requiredPriority = findPriorityForClass(cls);
                    // currentPriority < requiredPriority,如果当前用户注册进来的 Aop 代理类的级别,是低于我们要求的级别的,Spring 内部也会对它进行提升成我们要求的那个 class 类型
                    // 这样符合我们的建议:最好不要自己去使用低级别的自动代理创建器
                    if (currentPriority < requiredPriority) {
                        apcDefinition.setBeanClassName(cls.getName());
                    }
                }
                return null;
            }
            // 若用户自己没有定义,那就用系统定义好的:AnnotationAwareAspectJAutoProxyCreator
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            // 此处注意,增加了一个属性:最高优先级执行
            beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
            // 角色为 Spring 自己使用
            beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            // 注册此 Bean 定义信息
            registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
            return beanDefinition;
        }

    AnnotationAwareAspectJAutoProxyCreator:自动代理创建器,AOP 的核心

    先看 ProxyProcessorSupport

    // 继承 ProxyConfig,拥有 AOP 的基本配置
    public class ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean {
        // 把该 Bean 所有实现的接口,过滤后都作用在 ProxyFactory 上
        protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
            // 拿到该类所有实现的接口
            Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
            // 标记:是否存在“有问题的”代理接口,默认是 false
            boolean hasReasonableProxyInterface = false;
            for (Class<?> ifc : targetInterfaces) {
                // 判断这些接口是否是“有问题的”:既我们需要处理的
                if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) && ifc.getMethods().length > 0) {
                    hasReasonableProxyInterface = true;
                    break;
                }
            }
            // 说明除开哪些接口外,但凡有一个有用的接口,就 add 进去(这样就会采用 JDK 动态代理了)
            if (hasReasonableProxyInterface) {
                for (Class<?> ifc : targetInterfaces) {
                    proxyFactory.addInterface(ifc);
                }
            } else { // 否则直接采用 CGLIB
                proxyFactory.setProxyTargetClass(true);
            }
        }
    
        // InitializingBean...Aware 接口的子接口等,这些回调性质的接口
        protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
            return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||
                    AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
        }
    
        // 接口名称为这些的,也就是 spring aop 自己的东西
        protected boolean isInternalLanguageInterface(Class<?> ifc) {
            return (ifc.getName().equals("groovy.lang.GroovyObject") ||
                    ifc.getName().endsWith(".cglib.proxy.Factory") ||
                    ifc.getName().endsWith(".bytebuddy.MockAccess"));
        }

    再看 AbstractAutoProxyCreator

    AnnotationAwareAspectJAutoProxyCreator 是 AbstractAutoProxyCreator 的子类,AbstractAutoProxyCreator 是对自动代理创建器的一个抽象实现。重要的是,它实现了 SmartInstantiationAwareBeanPostProcessor 接口,因此会介入到 Spring IOC 容器 Bean 实例化的过程,SmartInstantiationAwareBeanPostProcessor 继承自 InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor, 所以它需要实现的方法有很多,重点说一下:在 Bean 被实例化之前,先会执行所有的 InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation,谁第一个返回了不为 null 的 Bean,后面就都不会执行了 。然后会再执行 BeanPostProcessor#postProcessAfterInitialization 就完事了

    主要看 postProcessBeforeInstantiation 方法和 postProcessAfterInitialization 方法,这两个是参与 Bean 实例化的

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
        /**
         * 在 Bean 实例化之前,给一个机会,看看缓存里有没有,有就直接返回了
         * 简单的说:其主要目的在于如果用户使用了自定义的 TargetSource 对象,则直接使用该对象生成目标对象,而不会使用 Spring 的默认逻辑生成目标对象
         * (并且这里会判断各个切面逻辑是否可以应用到当前 bean 上)
         */
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
            Object cacheKey = getCacheKey(beanClass, beanName);
    
            // beanName 无效或者 targetSourcedBeans 里不包含此 Bean
            if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
                // advisedBeans:已经被通知了的(被代理了的)Bean,如果在这里面,也返回 null
                if (this.advisedBeans.containsKey(cacheKey)) {
                    return null;
                }
                // isInfrastructureClass:Advice、Pointcut、Advisor、AopInfrastructureBean 的子类,表示是框架所属的 Bean
                // shouldSkip:默认都是返回 false 的。
                // AspectJAwareAdvisorAutoProxyCreator 重写此方法:只要存在一个 Advisor((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)成立 ,就返回 true
                if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                    // 所以这里会把我们所有的 Advice、Pointcut、Advisor、AopInfrastructureBean 等 Bean 都装进来
                    this.advisedBeans.put(cacheKey, Boolean.FALSE);
                    return null;
                }
            }
            // 到这,只有在 TargetSource 中没有进行缓存,并且应该被切面逻辑环绕,但是目前还未生成代理对象的 bean 才会通过此方法
    
            // Create proxy here if we have a custom TargetSource.
            // Suppresses unnecessary default instantiation of the target bean: The TargetSource will handle target instances in a custom fashion.
            // 如果我们有 TargetSourceCreator,这里就会创建一个代理对象
            // getCustomTargetSource 逻辑:存在 TargetSourceCreator 并且 beanFactory.containsBean(beanName) 然后遍历所有的 TargetSourceCreator,调用 getTargetSource 谁先创建不为 null 就终止
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
            // 若创建好了这个代理对象,继续进一步的操作
            if (targetSource != null) {
                if (StringUtils.hasLength(beanName)) {
                    // 缓存起来
                    this.targetSourcedBeans.add(beanName);
                }
                // getAdvicesAndAdvisorsForBean:方法判断当前 Bean 是否需要进行代理,若需要则返回满足条件的 Advice 或者 Advisor 集合
                // 这个方法由子类实现,AbstractAdvisorAutoProxyCreator 和 BeanNameAutoProxyCreator 代表中两种不同的代理方式
                Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                // 根据目标对象创建代理对象的核心逻辑了
                Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
                // 把创建好的代理缓存起来
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
    
            return null;
        }
    
        @Override
        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
            // 代理是通过 AbstractAutoProxyCreator 中的 postProcessAfterInitialization() 创建的
            // 因此这个方法是蛮重要的,主要是 wrapIfNecessary() 方法会特别的重要
            // earlyProxyReferences 缓存:该缓存用于保存已经创建过代理对象的 cachekey,避免重复创建
            if (bean != null) {
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
    
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            // 若此 Bean 已经在 targetSourcedBeans 里,说明已经被代理过,那就直接返回即可
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            // 如果该 Bean 是基础框架 Bean 或者免代理的 Bean,那也不处理
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            // 逻辑同上,对于实现了 Advice,Advisor,AopInfrastructureBean 接口的 bean,都认为是 spring aop 的基础框架类,不能对它们创建代理对象,
            // 同时子类也可以覆盖 shouldSkip 方法来指定不对哪些 Bean 进行代理
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // Create proxy if we have advice.
            // getAdvicesAndAdvisorsForBean 该方法由子类实现,如果有 Advice 切面切进去了,我们就要给它代理
            // 根据 getAdvicesAndAdvisorsForBean() 方法的具体实现的不同,AbstractAutoProxyCreator 又分成了两类自动代理机制
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            if (specificInterceptors != DO_NOT_PROXY) { // 需要代理,那就进来给它创建一个代理对象
                this.advisedBeans.put(cacheKey, Boolean.TRUE); // 缓存起来,赋值为 true,说明此 key 是被代理了的
                // 创建这个代理对象
                Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass()); // 创建好后缓存起来,避免重复创建
                return proxy;
            }
            // 把不需要代理的对象也给与缓存起来,赋值为 false
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    
        /**
         * 创建代理对象,specificInterceptors:作用在这个 Bean 上的增强器们
         * 这里需要注意的地方:入参是 targetSource,而不是 target
         * 所以最终代理的是`每次 AOP 代理处理方法调用时,目标实例都会用到 TargetSource 实现`
         */
        protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) {
            if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
                AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
            }
            // 创建代理对象的三大方式之一
            ProxyFactory proxyFactory = new ProxyFactory();
            // 复制当前类的相关配置,因为当前类它也是个 ProxyConfig
            proxyFactory.copyFrom(this);
    
            // 看看是否是基于类的代理(CGLIB),若表面上是基于接口的代理,我们还需要进一步去检测
            if (!proxyFactory.isProxyTargetClass()) {
                // shouldProxyTargetClass 方法用于判断是否应该使用 targetClass 类而不是接口来进行代理
                // 默认实现为和该 Bean 定义是否属性值 preserveTargetClass 为 true 有关。默认情况下都不会有此属性值的
                if (shouldProxyTargetClass(beanClass, beanName)) {
                    proxyFactory.setProxyTargetClass(true);
                } else {
                    // 到此处,就是把这个类实现的接口们,都放进 proxyFactory(当然也会处理一些特殊的接口,不算数的)
                    evaluateProxyInterfaces(beanClass, proxyFactory);
                }
            }
    
            // buildAdvisors:整理合并得到最终的 advisors(毕竟 interceptorNames 还指定了一些拦截器的)
            // 至于调用的先后顺序,通过 applyCommonInterceptorsFirst 参数可以进行设置,若 applyCommonInterceptorsFirst 为 true,interceptorNames 属性指定的 Advisor 优先调用。默认为 true
            Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
            proxyFactory.addAdvisors(advisors); // 添加进工厂里
            proxyFactory.setTargetSource(targetSource); // 把 targetSource 放进去,TargetSource 的实现方式有多种
            // 这个方法是交给子类的,子类可以继续去定制此 proxyFactory(Spring 内部并没重写,为空方法)
            customizeProxyFactory(proxyFactory);
    
            // 沿用 this 的 freezeProxy 属性值
            proxyFactory.setFrozen(this.freezeProxy);
            // 设置 preFiltered 的属性值,默认是 false。子类:AbstractAdvisorAutoProxyCreator 修改为 true
            // preFiltered 字段意思为:是否已为特定目标类筛选 Advisor
            // 这个字段和 DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice 获取所有的 Advisor 有关
            // CglibAopProxy 和 JdkDynamicAopProxy 都会调用此方法,然后递归执行所有的 Advisor
            if (advisorsPreFiltered()) {
                proxyFactory.setPreFiltered(true);
            }
            // getProxyClassLoader():调用者可指定,否则为:ClassUtils.getDefaultClassLoader()
            return proxyFactory.getProxy(getProxyClassLoader());
        }

    AbstractAutoProxyCreator#createProxy 方法中调用了 AbstractAutoProxyCreator#buildAdvisors 方法

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
        protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
            // 解析 interceptorNames 而来的 Advisor 数组
            Advisor[] commonInterceptors = resolveInterceptorNames();
            // 此处用的是 Object
            List<Object> allInterceptors = new ArrayList<>();
            if (specificInterceptors != null) {
                allInterceptors.addAll(Arrays.asList(specificInterceptors));
                if (commonInterceptors.length > 0) { // 若有内容
                    if (this.applyCommonInterceptorsFirst) { // 放在头部
                        allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
                    } else { // 放在末尾
                        allInterceptors.addAll(Arrays.asList(commonInterceptors));
                    }
                }
            }
            if (logger.isTraceEnabled()) {
                int nrOfCommonInterceptors = commonInterceptors.length;
                int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);
                logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");
            }
            // 把每一个 Advisor 都用 advisorAdapterRegistry.wrap() 包装一下
            Advisor[] advisors = new Advisor[allInterceptors.size()];
            for (int i = 0; i < allInterceptors.size(); i++) {
                // wrap 方法默认只支持三种类型的 Advice 转换为 Advisor
                advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
            }
            return advisors;
        }
    
        // 处理 interceptorNames,去容器内找出来
        private Advisor[] resolveInterceptorNames() {
            BeanFactory bf = this.beanFactory;
            ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null);
            List<Advisor> advisors = new ArrayList<>();
            for (String beanName : this.interceptorNames) {
                // 排除一些情况:此工厂不是 ConfigurableBeanFactory 或者该 Bean 不在创建中
                if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) {
                    Assert.state(bf != null, "BeanFactory required for resolving interceptor names");
                    // 拿到这个 Bean,然后使用 advisorAdapterRegistry 把它适配一下即可
                    Object next = bf.getBean(beanName);
                    advisors.add(this.advisorAdapterRegistry.wrap(next));
                }
            }
            return advisors.toArray(new Advisor[0]);
        }

    所有的创建器都是 AbstractAutoProxyCreator 该抽象类的子类,AbstractAutoProxyCreator 相当于一个代理创建的模版,规定了一些步骤。获取 Advisor 的 getAdvicesAndAdvisorsForBean 由各子类自己去实现。

    根据对 getAdvicesAndAdvisorsForBean() 的实现不一样,策略有两种。有两个直接实现:BeanNameAutoProxyCreator 和 AbstractAdvisorAutoProxyCreator。

    代理创建器可以分为三类:

    • 基于 Bean 配置名规则的自动代理生成器:允许为一组特定配置名的 Bean 自动创建代理实例的代理创建器,实现类为 BeanNameAutoProxyCreator
    • 基于 Advisor 匹配机制的自动代理创建器它会对容器中的所有 Advisor 进行扫描,自动将这些切面应用到匹配的 Bean 中,实现类是 DefaultAdvisorAutoProxyCreator(也支持前缀匹配)
    • 基于 Bean 中 AspectJ 注解的自动代理生成器:为包含 AspectJ 注解的切入的 Bean 自动创建代理实例

    先看 BeanNameAutoProxyCreator

    /**
     * 此时采用了 BeanNameAutoProxyCreator,自然就不用再 @EnableAspectJAutoProxy,自然 @Aspect 切面也就不生效了。
     * 当然,也可以开启的,这样他俩就联合生效了(但不太建议去这么使用)
     */
    @Bean
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        // 给所有以 serviceImpl 结尾的类创建代理对象(支持正则),备注:aliases 也是被支持的
        // 注意此处若只写`*Service`是匹配不上 helloServiceImpl
        beanNameAutoProxyCreator.setBeanNames("*ServiceImpl");
    
        // 备注:它要想使用拦截,只能通过 setInterceptorNames,从容器内拿 Advice 的实现类(自己书写)
        beanNameAutoProxyCreator.setInterceptorNames("logMethodBeforeAdvice");
        return beanNameAutoProxyCreator;
    }

    需要注意的是:如果一个对象被切多次(使用 @Async、事务都会创建代理对象),最终这个对象代理会是多层代理。

    如果想用自己注册的 Bean 代替 @EnableAspectJAutoProxy 默认注册的自动创建器,可以注册 Bean 名称为:AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME

    /**
     * @since 10.10.2003
     */
    public class BeanNameAutoProxyCreator extends AbstractAutoProxyCreator {
    
        @Nullable
        private List<String> beanNames;
    
        public void setBeanNames(String... beanNames) {
            Assert.notEmpty(beanNames, "'beanNames' must not be empty");
            this.beanNames = new ArrayList<>(beanNames.length);
            for (String mappedName : beanNames) {
                // 对 mappedName 做取出空白处理
                this.beanNames.add(StringUtils.trimWhitespace(mappedName));
            }
        }
    
        /**
         * BeanNameAutoProxyCreator 的此方法并没有去寻找 Advisor,需要拦截的话,只能依靠:setInterceptorNames() 来指定拦截器。它是根据名字去 Bean 容器里取的
         */
        @Override
        @Nullable
        protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
            if (this.beanNames != null) {
                for (String mappedName : this.beanNames) {
                    // 如果针对的是 FactoryBean,也是兼容的
                    if (FactoryBean.class.isAssignableFrom(beanClass)) {
                        if (!mappedName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
                            continue;
                        }
                        // 对 BeanName 进行处理,去除掉第一个字符
                        mappedName = mappedName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
                    }
                    if (isMatch(beanName, mappedName)) { // 匹配就返回 PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS,而不是再返回 null
                        return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
                    }
                    // 如果存在 Bean 工厂,哪怕任意一个 alias 匹配都是可以的
                    BeanFactory beanFactory = getBeanFactory();
                    if (beanFactory != null) {
                        String[] aliases = beanFactory.getAliases(beanName);
                        for (String alias : aliases) {
                            if (isMatch(alias, mappedName)) {
                                return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
                            }
                        }
                    }
                }
            }
            return DO_NOT_PROXY;
        }
    
        protected boolean isMatch(String beanName, String mappedName) {
            // simpleMatch 并不是完整的正则。但是支持 * 这种通配符,其余的不支持
            return PatternMatchUtils.simpleMatch(mappedName, beanName);
        }
    }

    DefaultAdvisorAutoProxyCreator

    类似 BeanNameAutoProxyCreator 的加强版,Spring 可以完成自动匹配的工作

    /**
     * 类似 BeanNameAutoProxyCreator 的加强版
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }
    
    /**
     * DefaultAdvisorAutoProxyCreator 还需要对应的 Advisor(可以有多个),从而给能够匹配上的创建代理对象了
     */
    @Bean
    public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor() {
        NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor = new NameMatchMethodPointcutAdvisor();
    
        // 拦截到了 HelloService#hello() 方法,因此会给他创建代理对象
        nameMatchMethodPointcutAdvisor.addMethodName("*hello");
    
        // 此处虽然 HelloController(子容器里) 有个方法名叫 helloGet,但是不会创建代理得。
        // 因为 NameMatchMethodPointcutAdvisor 在根容器里,不作用于子容器的 Bean
        nameMatchMethodPointcutAdvisor.addMethodName("helloGet");
        nameMatchMethodPointcutAdvisor.setAdvice(new LogMethodBeforeAdvice());
        return nameMatchMethodPointcutAdvisor;
    }

    这样它就会自动的去把 Advisor 匹配上的 Bean 进行代理掉。(不像 BeanNameAutoProxyCreator 还得手动指定 BeanName,以及拦截器们),一般都需要自己向容器注入自己的 Advisor,比如 NameMatchMethodPointcutAdvisor,否则它也不知道去代理谁。只有被对应的 Advisor 匹配上的才会生成代理对象。

    AbstractAdvisorAutoProxyCreator

    另一类自动代理方式,和 Advisor 有关(只有被切入的类,才会给它创建一个代理类),它的核心方法是实现了父类的:getAdvicesAndAdvisorsForBean 来获取 Advisor

    public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    
        @Nullable
        private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) {
            super.setBeanFactory(beanFactory);
            // 重写 setBeanFactory 方法,保证 bean 工厂是 ConfigurableListableBeanFactory
            if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
                throw new IllegalArgumentException("AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
            }
            // 对 advisorRetrievalHelper 进行初始化,找 advisor 最终是委托给它了
            initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
        }
    
        protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
        }
    
        private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {
            public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
                super(beanFactory);
            }
            @Override
            protected boolean isEligibleBean(String beanName) {
                return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
            }
        }
    
        /**
         * 这是复写父类的方法,也是实现代理方式。找到作用在这个 Bean 里面的切点方法
         * 当然,最终最终是委托给 BeanFactoryAdvisorRetrievalHelper 去做的
         */
        @Override
        @Nullable
        protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
            // findEligibleAdvisors:这个是具体的实现方法了。
            // eligible:合格的、合适的
            List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
    
        /**
         * 找出合适的 Advisor
         */
        protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
            // 首先找出所有候选的 Advisors,(根据名字判断)
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            // 对上面找到的候选的 Advisors 进行过滤操作,看看 Advisor 能否被用在 Bean 上(根据 Advisor 的 PointCut 判断)
            // 主要依赖于 AopUtils.findAdvisorsThatCanApply() 方法
            // 逻辑简单概述为:看目标类是不是符合代理对象的条件,如果符合就把 Advisor 加到集合中,最后返回集合
            // 简单的说:它就是会根据 ClassFilter 和 MethodMatcher 等各种匹配。(但凡有一个方法被匹配上了,就会给它创建代理类)
            // 方法用的 ReflectionUtils.getAllDeclaredMethods,因此就算是私有方法,匹配上都会给创建代理对象
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            // 提供一个钩子。子类可以复写此方法,然后对 eligibleAdvisors 进行处理(增加/删除/修改等等)
            // AspectJAwareAdvisorAutoProxyCreator 提供了实现
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) { // 如果最终还有,就排序
                // 默认排序方式:AnnotationAwareOrderComparator.sort() 排序,这个排序和 Order 接口有关
                // 子类 AspectJAwareAdvisorAutoProxyCreator 有复写此排序方法,需要注意
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }
    
        /**
         * 找到候选的 Advisor,抽象类自己的实现,是直接把这件事委托给了 advisorRetrievalHelper
         * AnnotationAwareAspectJAutoProxyCreator 对它有复写
         */
        protected List<Advisor> findCandidateAdvisors() {
            Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
            return this.advisorRetrievalHelper.findAdvisorBeans();
        }
    
        /**
         * 判断给定的 BeanName 这个 Bean,是否是合格的(BeanFactoryAdvisorRetrievalHelper 里会用到这个属性)
         * 其中:DefaultAdvisorAutoProxyCreator 和 InfrastructureAdvisorAutoProxyCreator 有复写
         */
        protected boolean isEligibleAdvisorBean(String beanName) {
            return true;
        }
    
        @Override
        protected boolean advisorsPreFiltered() {
            return true;
        }

    AspectJAwareAdvisorAutoProxyCreator

    主要来处理AspectJ切面

    public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
    
        // 默认的排序器,不是根据 Order 来了,而是根据 @Afeter @Before 类似的标注来排序
        private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();
    
        /**
         * 核心逻辑:重写了排序,控制着最终的执行顺序
         * 这个排序和`org.aspectj.util`提供的 PartialOrder 和 PartialComparable 有关
         */
        @Override
        protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
            List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
            for (Advisor advisor : advisors) {
                partiallyComparableAdvisors.add(PartiallyComparableAdvisorHolder(advisor, DEFAULT_PRECEDENCE_COMPARATOR));
            }
            List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
            if (sorted != null) {
                List<Advisor> result = new ArrayList<>(advisors.size());
                for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
                    result.add(pcAdvisor.getAdvisor());
                }
                return result;
            } else {
                return super.sortAdvisors(advisors);
            }
        }
    
        /**
         * 这个就是对已有的 Advisor 做了一个扩展:
         * AspectJProxyUtils 这个工具类只有这一个方法(其实每次 addAspect() 的时候,都会调用此方法)
         * Capable:能干的、有才华的
         * 它的作用:若存在 AspectJ 的 Advice,就会在 advisors 的第一个位置加入`ExposeInvocationInterceptor.ADVISOR` 这个 advisor
         */
        @Override
        protected void extendAdvisors(List<Advisor> candidateAdvisors) {
            AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
        }
    
        @Override
        protected boolean shouldSkip(Class<?> beanClass, String beanName) {
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            // 相当于 AspectJPointcutAdvisor 的子类不要拦截、AspectJ 切面自己的所有方法不要去拦截
            for (Advisor advisor : candidateAdvisors) {
                if (advisor instanceof AspectJPointcutAdvisor &&
                        ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                    return true;
                }
            }
            // 父类返回的 false
            return super.shouldSkip(beanClass, beanName);
        }

    AnnotationAwareAspectJAutoProxyCreator

    public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
    
        @Nullable
        private List<Pattern> includePatterns;
    
        /**
         * 唯一实现类:ReflectiveAspectJAdvisorFactory
         * 作用:基于 @Aspect 时,创建 Spring AOP 的 Advice
         * 里面会对标注这些注解 Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class 的方法进行排序
         * 然后把他们都变成 Advisor(getAdvisors()方法)
         */
        @Nullable
        private AspectJAdvisorFactory aspectJAdvisorFactory;
    
        /**
         * 用来从 bean 容器,也就是 BeanFactory 中获取所有使用了 @AspectJ 注解的 bean
         * 就是这个方法:aspectJAdvisorsBuilder.buildAspectJAdvisors()
         */
        @Nullable
        private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
    
    
        /**
         * 支持自定义一个正则的模版,isEligibleAspectBean() 该方法使用此模版,从而决定使用哪些 Advisor
         */
        public void setIncludePatterns(List<String> patterns) {
            this.includePatterns = new ArrayList<>(patterns.size());
            for (String patternText : patterns) {
                this.includePatterns.add(Pattern.compile(patternText));
            }
        }
    
        // 可以自己实现一个 AspectJAdvisorFactory,否则用默认的 ReflectiveAspectJAdvisorFactory
        public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
            Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
            this.aspectJAdvisorFactory = aspectJAdvisorFactory;
        }
    
        @Override
        protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            // 此处一定要记得调用 super.initBeanFactory(beanFactory);
            super.initBeanFactory(beanFactory);
            if (this.aspectJAdvisorFactory == null) {
                this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
            }
            this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
        }
    
        /**
         * 拿到所有的候选的 advisor。请注意:这里没有先调用了父类的 super.findCandidateAdvisors() 去容器里找出来一些
         * 然后自己又通过 aspectJAdvisorsBuilder.buildAspectJAdvisors() 解析 @Aspect 的方法得到一些 Advisor
         */
        @Override
        protected List<Advisor> findCandidateAdvisors() {
            List<Advisor> advisors = super.findCandidateAdvisors();
            if (this.aspectJAdvisorsBuilder != null) {
                advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
            }
            return advisors;
        }
    
        // 加了种类型,如果该 Bean 自己本身就是一个 @Aspect,那也认为是基础组件,不要切了
        @Override
        protected boolean isInfrastructureClass(Class<?> beanClass) {
            return (super.isInfrastructureClass(beanClass) || (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
        }
    
        // 拿传入的正则模版进行匹配(没传就返回 true,所有的 Advisor 都会生效)
        protected boolean isEligibleAspectBean(String beanName) {
            if (this.includePatterns == null) {
                return true;
            } else {
                for (Pattern pattern : this.includePatterns) {
                    if (pattern.matcher(beanName).matches()) {
                        return true;
                    }
                }
                return false;
            }
        }
    
        private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {
            public BeanFactoryAspectJAdvisorsBuilderAdapter(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
                super(beanFactory, advisorFactory);
            }
    
            @Override
            protected boolean isEligibleBean(String beanName) {
                return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
            }
        }
    }

    BeanFactoryAdvisorRetrievalHelper

    AbstractAdvisorAutoProxyCreator 中使用的工具类,用来从容器中找出所有的 Advisor 类

    public class BeanFactoryAdvisorRetrievalHelper {
    
        private static final Log logger = LogFactory.getLog(BeanFactoryAdvisorRetrievalHelper.class);
    
        private final ConfigurableListableBeanFactory beanFactory;
    
        // 本地做一个简单的字段缓存
        @Nullable
        private volatile String[] cachedAdvisorBeanNames;
    
        public BeanFactoryAdvisorRetrievalHelper(ConfigurableListableBeanFactory beanFactory) {
            Assert.notNull(beanFactory, "ListableBeanFactory must not be null");
            this.beanFactory = beanFactory;
        }
    
        public List<Advisor> findAdvisorBeans() {
            String[] advisorNames = this.cachedAdvisorBeanNames;
            if (advisorNames == null) {
                // 这里不会实例化 FactoryBeans
                // 我们需要保留所有常规 bean,未初始化,以允许自动代理创建者应用于它们
                // 注意此处:连祖先容器里面的 Bean 都会拿出来(这个方法平时我们也可以使用)
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
                this.cachedAdvisorBeanNames = advisorNames;
            }
            if (advisorNames.length == 0) {
                return new ArrayList<>();
            }
    
            List<Advisor> advisors = new ArrayList<>();
            for (String name : advisorNames) {
                // isEligibleBean:表示这个 bean 是否是合格的,默认是 true
                // InfrastructureAdvisorAutoProxyCreator 和 DefaultAdvisorAutoProxyCreator 都对 isEligibleBean 复写了
                if (isEligibleBean(name)) {
                    // 如果当前 Bean 正在创建中,那就什么也不做
                    if (this.beanFactory.isCurrentlyInCreation(name)) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Skipping currently created advisor '" + name + "'");
                        }
                    } else { // 否则就把这个 Advisor 加入到 List 里,是个合法的
                        try {
                            advisors.add(this.beanFactory.getBean(name, Advisor.class));
                        } catch (BeanCreationException ex) {
                            Throwable rootCause = ex.getMostSpecificCause();
                            if (rootCause instanceof BeanCurrentlyInCreationException) {
                                BeanCreationException bce = (BeanCreationException) rootCause;
                                String bceBeanName = bce.getBeanName();
                                if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                                    if (logger.isTraceEnabled()) {
                                        logger.trace("Skipping advisor '" + name + "' with dependency on currently created bean: " + ex.getMessage());
                                    }
                                    continue;
                                }
                            }
                            throw ex;
                        }
                    }
                }
            }
            return advisors;
        }
    
        protected boolean isEligibleBean(String beanName) {
            return true;
        }
    }

    Advisor(Advice + Pointcut) 创建过程

    Advisor 中的 Pointcut 与 Advice 都是由 ReflectiveAspectJAdvisorFactory 来解析生成的

    与之对应的 Advice 是 AspectJMethodBeforeAdvice、AspectJAfterAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice、AspectJAroundAdvice

    与之对应的 Pointcut 则是 AspectJExpressionPointcut

    解析的步骤是:

    1. 自动代理创建器:AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
    2. Bean工厂相关的Advisor构建器:BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
    3. ReflectiveAspectJAdvisorFactory.getAdvisors()
    4. ReflectiveAspectJAdvisorFactory.getAdvisor() 最终生成了 InstantiationModelAwarePointcutAdvisorImpl(包括里面的 Pointcut 与 Advice 也都是由 ReflectiveAspectJAdvisorFactory 解析生成的)

    https://blog.csdn.net/f641385712/article/details/88904864

    https://blog.csdn.net/f641385712/article/details/88904983

    https://javadoop.com/post/spring-aop-source

  • 相关阅读:
    客户端用mstsc不能用一台设备连接终端服务器的解决办法
    [转]知识管理ABC
    Visual Studio常用小技巧[备忘]
    一套外企的数据库设计面试题
    MSDN中的图形元素和文档约定[备忘]
    设计模式概述
    ASP.Net 4.0中新增加的23项功能[转]
    Dreamweaver 8 的相关使用
    浅谈ThreadPool 线程池
    C#委托的异步调用[学习]
  • 原文地址:https://www.cnblogs.com/jhxxb/p/13998035.html
Copyright © 2020-2023  润新知