• spring aop 创建代理流程


    前言

    ​ 查看spring怎么为需要进行aop控制的类创建代理的,探索spring创建代理的流程,以及怎么创建代理。

    代理

    代理分为动态代理和静态代理,动态代理是在运行时生成代理类,静态代理是在编译阶段已经生成了代理类。

    jdk 和 CGLIB 都支持动态代理,他们的区别:

    ​ 1. jdk 动态代理的是接口,如果类没有实现接口,则无法进行代理,如果实现类中的方法未在接口中声明的,则对该方法进行代理时会抛出异常;

    ​ 2. 而 CGLIB 是通过继承目标类来实现的,由于通过继承来实现代理的,所以无法代理 final 修饰符的类,也无法代理静态方法。

    AspectJ 支持静态代理,通过编译器将代理代码编织进目标class中,他支持在编译时织入、编译后织入、类加载后织入,能够实现 jdk代理 和 CGLIB 代理不能实现的功能。

    AspectJ 代理由于是静态代理,效率最高,CGLIB代理比JDK代理效率高 ( AspectJ > CGLIB > JDK ) 。

    Spring AOP
    Advisor作用

    ​ spring 的代理中,使用 Advisor 接口来进行统一管理切入点 Pointcut和通知Advcice

    public interface Advisor {
       // 默认空的通知
       Advice EMPTY_ADVICE = new Advice() {};
       // 持有的通知
       Advice getAdvice();
       // 暂时未使用
       boolean isPerInstance();
    }
    
    // 切入点
    public interface Pointcut {
        // 类匹配器,自定义匹配规则
        ClassFilter getClassFilter();
        // 方法匹配器
        MethodMatcher getMethodMatcher();
        // 匹配所有方法
        Pointcut TRUE = TruePointcut.INSTANCE;
    }
    
    // 切入点类匹配器
    @FunctionalInterface
    public interface ClassFilter {
    	// 匹配规则
    	boolean matches(Class<?> clazz);
    	// 匹配所有的类
    	ClassFilter TRUE = TrueClassFilter.INSTANCE;
    }
    
    // 切入点方法匹配器
    public interface MethodMatcher {
    	// 方法匹配器:静态匹配,匹配规则不严格
    	boolean matches(Method method, Class<?> targetClass);
    	// 是否进行动态匹配,为true调用动态匹配,否则不调用
    	boolean isRuntime();
    	// 方法匹配器:动态匹配,包括参数
    	boolean matches(Method method, Class<?> targetClass, Object... args);
    	// 匹配所有方法
    	MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
    }
    

    Advisor 的结构图如下:

    Advisor的子接口主要有 IntroductionAdvisorPointcutAdvisorIntroductionAdvisor 只能实现类的拦截,而 PointcutAdvisor能实现方法级别的拦截,功能更加强大。

    下面查看 spring 是怎么为AOP控制的类或方法创建代理的。

    代理创建器

    ​ spring 提供了三个代理创建类 InfrastructureAdvisorAutoProxyCreator、AspectJAwareAdvisorAutoProxyCreator、AnnotationAwareAspectJAutoProxyCreator,功能如下。

    InfrastructureAdvisorAutoProxyCreator :处理spring内部需要代理的 bean(ROLE = ROLE_INFRASTRUCTURE)。

    AspectJAwareAdvisorAutoProxyCreator :使用 AspectJ 来进行动态代理,支持 AspectJ表达式和根据通知类型按序增强,支持所有的bean。

    AnnotationAwareAspectJAutoProxyCreator:支持使用注解的方式声明切入点,是 AspectJAwareAdvisorAutoProxyCreator 的子类,使用 @EnableAspectJAutoProxy 后自动导入该代理创建器,是最广泛使用的。

    注册 Proxy 创建器

    spring boot 自动配置模块 spring-boot-autoconfigurespring.factories 中通过导入配置类 AopAutoConfiguration 的方式将 AnnotationAwareAspectJAutoProxyCreator 注册进 spring ,通过调用 AopConfigUtils 将上面三个代理类进行配置和注册到 BeanDefinitionRegistry

    AnnotationAwareAspectJAutoProxyCreator 继承结构。

    创建Proxy

    AnnotationAwareAspectJAutoProxyCreator 的父类 AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation(Class<?> beanClass, String beanName) ,可以替换spring 内置bean的创建流程,将bean替换为代理类。

    1. 在启动spring boot项目时,加载 AnnotationAwareAspectJAutoProxyCreator
    2. spring 创建 bean 前调用 AbstractAutoProxyCreator#postProcessBeforeInstantiation()
    3. spring 默认只会为一个bean创建一次代理,所以创建过代理的就直接返回。
    4. 找到自定义的 TargetSourceCreator ,使用他来创建 TargetSource,如果没有自定义 TargetSourceCreator ,就不会创建代理直接返回null。
    5. 创建 TargetSource 后,找到该 bean 匹配的切入点或通知,然后根据对应的切入点或通知来创建代理。
    6. 如果创建代理成功,代理 bean 注入 spring 容器中;如果未创建或创建失败,则进入 spring 内置的bean创建流程,后续在创建完bean之后并且调用了 init-method 方法后执行 AbstractAutoProxyCreator#postProcessAfterInitialization() 来继续创建代理。
    7. AbstractAutoProxyCreator#postProcessAfterInitialization() 中使用 SingletonTargetSource 来包装bean,并找到该bean或bean 方法匹配的切入点来创建代理。
    8. 创建代理成功后,在执行bean的方法时,就会执行切入点(pointcut)对应通知(advice)的逻辑。

    AbstractAutoProxyCreator#postProcessBeforeInstantiation 方法:

    // AbstractAutoProxyCreator
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
       // 生成一个缓存key,如果提供了beanName,并且是`FactoryBean`的实现类,则使用"$"+beanName,不是`FactoryBean`实现类则使
       // 用BeanName;如果没有提供beanName,使用 beanClass 作为 cacheKey。
       Object cacheKey = getCacheKey(beanClass, beanName);
    
       // 未提供 beanName 或 beanName不在缓存中
       if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
          // 已经处理过,记录了该类不需要代理
          if (this.advisedBeans.containsKey(cacheKey)) {
             return null;
          }
          //isInfrastructureClass: 该类是Advice、Pointcut、Advisor、AopInfrastructureBean 的实现类,代表了不需要去代理他
          // shouldSkip:判断该类是否是原始类,类名称或beanName使用 ".ORIGINAL" 结尾的代表不能进行代理
          // shouldSkip:在 AbstractAutoProxyCreator 中,如果bean是AspectJPointcutAdvisor实现类,也将跳过,不进行代理
          if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
             // 记录该类的实例不能进行代理
             this.advisedBeans.put(cacheKey, Boolean.FALSE);
    		 // 返回 null 表示不进行代理,交给其他实现了 postProcessBeforeInstantiation 方法的类处理或 进行正常的创建bean流程
             return null;
          }
       }
    
       // 创建自定义的 targetSource, targetSource 可以用来管理多个代理对象
       // 在 targetSource 中绑定了一个内部使用的 BeanFactory。
       TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        
       if (targetSource != null) {
          if (StringUtils.hasLength(beanName)) {
             this.targetSourcedBeans.add(beanName);
          }
          // 获取当前 bean 可以匹配的 Advisor
          Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
          // 创建代理对象,其实创建的是 TargetSource 的代理对象,然后通过 TargetSource 来达到管理多个对象。
          Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
          // 缓存
          this.proxyTypes.put(cacheKey, proxy.getClass());
          // 返回代理对象,spring 就不会进行后续的对象创建,而是管理这个代理对象。
          return proxy;
       }
       return null;
    }
    

    AbstractAutoProxyCreator#postProcessAfterInitialization 主体:

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
       // bean 不为空
       if (bean != null) {
          // 获取缓存Key
          Object cacheKey = getCacheKey(bean.getClass(), beanName);
          // 将缓存与当前bean进行比较,如果不一致,返回代理对象
          if (this.earlyProxyReferences.remove(cacheKey) != bean) {
             return wrapIfNecessary(bean, beanName, cacheKey);
          }
       }
       return bean;
    }
    
    /**
     * 创建代理对象
     */
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 获取bean,如果bean已经被处理过,直接返回
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 不进行代理:直接返回bean
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        // 判断是否需要代理:beanClass 不是AOP基础结构类Advice以及是spring 指定不需要进行代理的类
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    
        // 获取通知 advisor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            // 创建代理
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // SingletonTargetSource 做为代理目标数据源,通过TargetSource 来操作 targetBean
            Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
    
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    

    ​ 上面介绍了 PointcutAdvisorIntroductionAdvisor的作用,在查找bean能匹配的切入点中,会将父类与接口的方法跟spring容器中的 PointcutAdvisorIntroductionAdvisor 进行匹配,匹配规则是委托给 PointcutClassFilter 的,如果满足则将切入点返回集合中统一返回,之后对切入点进行排序。

    AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean 获取bean可以匹配通知 Advisor 集合:

    /** 
     * AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
     * 获取 beanClass 能匹配的切入点
     */
    protected Object[] getAdvicesAndAdvisorsForBean(
          Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
       // 寻找能匹配的切入点
       List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
       if (advisors.isEmpty()) {
          return DO_NOT_PROXY;
       }
       return advisors.toArray();
    }
    
    /**
     * AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
     * 从 spring 容器中,找到所有的切入点与通知,然后与 beanClass 进行匹配
     */
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        // 标记1. 从BeanFactory 中获取 所有的切入点:Advisor 类型的bean对象
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        
        // 标记2. 将 (beanClass、beanName) 与 candidateAdvisors 进行匹配,将匹配的切入点返回。
        // 匹配规则各异,有按照注解、方法名、方法参数、bean名称来进行匹配。
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        
        // 扩展
        extendAdvisors(eligibleAdvisors);
        // 排序
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }
    

    标记1:从spring 容器中查找所有的 Advisor

    /**
     * AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
     * 标记1. 从BeanFactory 中获取 所有的切入点:Advisor 类型的bean对象
     */
    protected List<Advisor> findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 标记1.1 调用 AbstractAdvisorAutoProxyCreator#findCandidateAdvisors(),查找spring 容器中的 Advisor
        List<Advisor> advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        if (this.aspectJAdvisorsBuilder != null) {
            // 标记1.2 添加额外的 Advisors,这里就将一个方法对应一个代理类,来进行代理逻辑处理
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
    
    /**
      * 标记1.1 AbstractAdvisorAutoProxyCreator#findCandidateAdvisors
      * 查找spring 容器中的 Advisor
      */
    protected List<Advisor> findCandidateAdvisors() {
        Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    	// 标记1.1
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }
    
    /**
     * BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()
     *
     * 标记1.1 从BeanFactory 中获取 所有的切入点:Advisor 类型的bean对象
     */
    public List<Advisor> findAdvisorBeans() {
        // 获取已经缓存 spring 容器中 Advisor 类型的 beanName
        // Determine list of advisor bean names, if not cached already.
        String[] advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // 查找 spring 容器中 Advisor 类型的 beanName ,放入缓存中
            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) {
            // 判断beanName
            if (isEligibleBean(name)) {
                // bean 正在创建过程中,则跳过该次寻找
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Skipping currently created advisor '" + name + "'");
                    }
                }
                else {
                    try {
                        // 根据beanName 和 类型获取 Advisor 类型的 bean
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    catch (BeanCreationException ex) {
                        // 异常处理代码... 略
                        throw ex;
                    }
                }
            }
        }
        return advisors;
    }
    
    
    /**
     * 标记1.2 添加额外的 Advisors
     * AnnotationAwareAspectJAutoProxyCreator 添加额外的 Advisor
     * BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
     */
    public List<Advisor> buildAspectJAdvisors() {
        // 缓存 aspect 注解类的beanName
        List<String> aspectNames = this.aspectBeanNames;
    	// 缓存为空
        if (aspectNames == null) {
            // 对this加锁
            synchronized (this) {
                // 再次检查 aspectBeanNames 是否为空
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    // 查找所有的bean
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                        this.beanFactory, Object.class, true, false);
                    // 循环处理
                    for (String beanName : beanNames) {
                        // 判断该bean是否满足匹配条件
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // 获取bean的class
                        Class<?> beanType = this.beanFactory.getType(beanName, false);
                        if (beanType == null) {
                            continue;
                        }
                        // 是 Advisor 实现:使用了 @Aspect 注解,并且字段名称不带有 ajc$ 前缀
                        if (this.advisorFactory.isAspect(beanType)) {
                            // 添加到集合中
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            // 单例
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory =
                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                // 解析方法或字段得到Advisor:使用了 @Pointcut  和 @DeclareParents
                                // 一个方法或一个字段对应了一个 Advisor,独立的进行代理
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                // bean的作用域是单例的将Advisor添加到缓存
                                if (this.beanFactory.isSingleton(beanName)) {
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    // bean的作用域不是单例的,则缓存工厂
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                advisors.addAll(classAdvisors);
                            }
                            else {
                                // 是单例
                                if (this.beanFactory.isSingleton(beanName)) {
                                    throw new IllegalArgumentException("Bean with name '" + beanName +
                                                                       "' is a singleton, but aspect instantiation model is not singleton");
                                }
                                // 
                                MetadataAwareAspectInstanceFactory factory =
                                    new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                this.aspectFactoryCache.put(beanName, factory);
                                // 解析
                                advisors.addAll(this.advisorFactory.getAdvisors(factory));
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }
    
        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        List<Advisor> advisors = new ArrayList<>();
        for (String aspectName : aspectNames) {
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                // 缓存
                advisors.addAll(cachedAdvisors);
            }
            else {
                // 解析
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        // 返回缓存内容
        return advisors;
    }
    
    /**
     * ReflectiveAspectJAdvisorFactory#getAdvisors()
     * 解析bean的注解
     */
    @Override
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        validate(aspectClass);
    	
        // 根据方法进行解析
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
            new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
    
        List<Advisor> advisors = new ArrayList<>();
        // 获取class 中使用了Pointcut注解的方法集合
        for (Method method : getAdvisorMethods(aspectClass)) {
            // 获取advisor
            Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }
    
        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }
    
        for (Field field : aspectClass.getDeclaredFields()) {
            Advisor advisor = getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }
    
        return advisors;
    }
    /**
     * ReflectiveAspectJAdvisorFactory#getAdvisor()
     * 获取方法对应的通知
     */
    @Override
    @Nullable
    public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                              int declarationOrderInAspect, String aspectName) {
        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        // 找到切入点,使用了 Around , Before, After, AfterReturnings, AfterThrowing 注解的方法。
        AspectJExpressionPointcut expressionPointcut = getPointcut(
            candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
        if (expressionPointcut == null) {
            return null;
        }
        // 将切入点封装成InstantiationModelAwarePointcutAdvisorImpl,一个切入点方法对应一个该类型的对象,其中封装了切入点信息、方法、参数等信息。
        // InstantiationModelAwarePointcutAdvisorImpl 会调用 ReflectiveAspectJAdvisorFactory#getAdvice() 方法获取具体的通知。
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                                                              this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
    /**
     * ReflectiveAspectJAdvisorFactory#getAdvice() 
     * 获取对应的通知,在创建 InstantiationModelAwarePointcutAdvisorImpl 时中会调用该方法
     */
    public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
                            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    
        Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        validate(candidateAspectClass);
    
        AspectJAnnotation<?> aspectJAnnotation =
            AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    	// ... 略
        AbstractAspectJAdvice springAdvice;
    
        // 根据注解类型获取对应的通知
        switch (aspectJAnnotation.getAnnotationType()) {
            case AtPointcut:
                if (logger.isDebugEnabled()) {
                    logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }
                return null;
            // 环绕通知
            case AtAround: 
                springAdvice = new AspectJAroundAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            // 前置t
            case AtBefore:
                springAdvice = new AspectJMethodBeforeAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfter:
                springAdvice = new AspectJAfterAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            case AtAfterReturning:
                springAdvice = new AspectJAfterReturningAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                    springAdvice.setReturningName(afterReturningAnnotation.returning());
                }
                break;
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(
                    candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            default:
                throw new UnsupportedOperationException(
                    "Unsupported advice type on method: " + candidateAdviceMethod);
        }
    
        // Now to configure the advice...
        springAdvice.setAspectName(aspectName);
        springAdvice.setDeclarationOrder(declarationOrder);
        String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
        if (argNames != null) {
            springAdvice.setArgumentNamesFromStringArray(argNames);
        }
        springAdvice.calculateArgumentBindings();
    
        return springAdvice;
    }
    

    标记2:把spring容器内找到的 Advisor 与 目标代理 bean 或 目标代理beanClass 进行匹配,查找符合的Advisor

    
    /**
     * BeanFactoryAdvisorRetrievalHelper.findAdvisorsThatCanApply()
     * 
     * 2. 从spring 容器中找到的 Advisor 与 beanClass 或 beanName 匹配,将匹配到的切入点返回
     */
    protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
        // 将当前正在匹配的beanName绑定到线程上
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            // 解绑
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
    
    /**
     * 
     * AopUtils.findAdvisorsThatCanApply 
     * 标记2:对bean进行能够匹配的 Advisor
     */
    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        List<Advisor> eligibleAdvisors = new ArrayList<>();
        for (Advisor candidate : candidateAdvisors) {
            // IntroductionAdvisor 实现类级别的拦截。
            // 如果是 IntroductionAdvisor 实现类,并且与该类的匹配规则匹配,加入返回集合中。
            // IntroductionAdvisor#getClassFilter() 返回一个 ClassFilter ,使用ClassFilter来进行匹配规则的处理
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        // 已经匹配了 IntroductionAdvisor 类型的切入点
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
            // 跳过,前面已经处理过
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            // 匹配
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
    
    /**
     * 标记2:根据类型不同,进行不同的匹配规则
     */
    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        
        // 对类级别进行拦截,与切入点无关
        if (advisor instanceof IntroductionAdvisor) {
            // 将匹配规则委托给 ClassFilter
            return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }
        // 切入点,实现更细化的匹配规则,如方法、方法名称等
        else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            // 没有切入点默认匹配
            // It doesn't have a pointcut so we assume it applies.
            return true;
        }
    }
    
    /**
     * 标记2:将 bean 与 PointcutAdvisor 进行匹配
     */ 
    public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        
        // 按类进行匹配
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        }
    
        // 方法匹配器
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        // 匹配所有方法,直接返回true
        if (methodMatcher == MethodMatcher.TRUE) {
            return true;
        }
    
        // 方法匹配器
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }
    
        Set<Class<?>> classes = new LinkedHashSet<>();
        // 返回目标对象的用户定义类,如果是代理 class,则将返回目标代理class,不是代理对象则直接返回 targetClass
        if (!Proxy.isProxyClass(targetClass)) {
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        // 添加所有的接口,包括父类实现的接口
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    
        //  targetClass 的父类和接口与切入点进行匹配
        for (Class<?> clazz : classes) {
            
            // 获取所有的方法
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
            for (Method method : methods) {
                // 进行匹配
                if (introductionAwareMethodMatcher != null ?
                    // 执行匹配动作(AspectJExpressionPointcut 解析注解表达式)
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                    methodMatcher.matches(method, targetClass)) {
                    return true;
                }
            }
        }
    
        return false;
    }
    

    AbstractAutoProxyCreator#createProxy :创建代理

    /**
     * 创建代理
     */
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
          @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
       // 暴露目标类的class:将 beanClass 绑定到
       if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
          AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
       }
       // 代理工厂
       ProxyFactory proxyFactory = new ProxyFactory();
       proxyFactory.copyFrom(this);
    
       // 是否已经被代理了
       if (!proxyFactory.isProxyTargetClass()) {
          // 使用子类来进行代理
          if (shouldProxyTargetClass(beanClass, beanName)) {
             proxyFactory.setProxyTargetClass(true);
          }
           // 使用接口代理
          else {
             evaluateProxyInterfaces(beanClass, proxyFactory);
          }
       }
    
       // 将Advisor和拦截器组合
       Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
       // 将Advisor添加到代理工厂中
       proxyFactory.addAdvisors(advisors);
       // 设置targetSource
       proxyFactory.setTargetSource(targetSource);
       customizeProxyFactory(proxyFactory);
    
       // 冻结 proxyFactory 的属性:如果为true,之后都不能进行更改属性,false则可以
       proxyFactory.setFrozen(this.freezeProxy);
        
       // 是否已经对Advisor进行了过虑,如果没有进行过虑,在之后会进行过虑
       if (advisorsPreFiltered()) {
          proxyFactory.setPreFiltered(true);
       }
       // 生成代理:如果 ProxyTargetClass = true,或者该 bean 没有实现接口,则使用子类来代理。
       return proxyFactory.getProxy(getProxyClassLoader());
    }
    
  • 相关阅读:
    输入流输出流打印到文件
    前缀和
    树形dp
    快速幂 ,快速幂优化,矩形快速幂(java)
    尾递归
    java中bigInteger的应用
    求树的最大直径
    买不到的数目
    ccpc 长春站 G
    大学ACM第二周心得
  • 原文地址:https://www.cnblogs.com/diandiandidi/p/14559018.html
Copyright © 2020-2023  润新知