Spring-Aop 底层源码解析--Spring中Aspect切面逻辑的实现

2023-12-13 03:45:34


前言

在Spring项目中我们可以在启动类上开启切面,并为已经存在的bean 增加@Aspect 声明为切面类,这样就可以为特定bean 中的方法增加对应的逻辑,那么Spring对于@Aspect 是如何支持的呢?


一、 aop 的相关概念:

  • Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等
  • Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个- 连接点通常表示一个方法的执行。
  • Advice:表示通知,表示在一个特定连接点上所采取的动作。Advice分为不同的类型,后面详细讨论,在很多AOP框架中,包括Spring,会用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链
  • Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上
  • Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现
  • Target object:目标对象,被代理对象
  • AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理
  • Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时,比如Spring AOP

二、Spring Aspect 切面的实现:

2.1 准备工作:

启动类中增加切面扫描注解

@EnableAspectJAutoProxy

定义切面:

@Aspect
@Component
public class TestAspect {

    @Before("execution(public void  com.example.springdabaihua.aspect.service.AspectTestService.test())")
    public  void  test(JoinPoint joinPoint){
        System.out.println("test() before");
    }
}

2.2 Spring 对切面的扫描:

2.2.1 初始的bean 定义工作:

EnableAspectJAutoProxy:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;

    boolean exposeProxy() default false;
}

可以看到注如了一个AspectJAutoProxyRegistrar 类型的 bean
AspectJAutoProxyRegistrar :

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		// bean 的注册 ,注册 AnnotationAwareAspectJAutoProxyCreator 类型的bean
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		// 注册完成 获取EnableAspectJAutoProxy  的属性值 然后进行属性设置
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {

            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    }
}

AopConfigUtils registerAspectJAnnotationAutoProxyCreatorIfNecessary 对于切面的扫描:

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, (Object)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("org.springframework.aop.config.internalAutoProxyCreator")) {
        BeanDefinition apcDefinition = registry.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }

        return null;
    } else {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", Integer.MIN_VALUE);
        beanDefinition.setRole(2);
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
        return beanDefinition;
    }
}

最终在创建某个bean 初始化之后会调用到父类AbstractAutoProxyCreator 的postProcessAfterInitialization 方法,判断改bean是否需要进行aop :

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
        	// 对创建的bean 进行包装
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }

    return bean;
}

对bean 进行下包装:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
		// 是否有切面的逻辑,由切面 需要进行aop
		//  获取当前的bean 与存在的advisor 能够匹配上  ,对bean 的类进行匹配 获取到匹配的advisor
        Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
        if (specificInterceptors != DO_NOT_PROXY) {
			// 如果有匹配到的advisor 则需要进行aop
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 对当前的bean 创建代理对象,specificInterceptors 为代理逻辑advisor
            Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    } else {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
}

isInfrastructureClass 进行是否有切面的逻辑:

protected boolean isInfrastructureClass(Class<?> beanClass) {
    boolean retVal = Advice.class.isAssignableFrom(beanClass) || Pointcut.class.isAssignableFrom(beanClass) || Advisor.class.isAssignableFrom(beanClass) || AopInfrastructureBean.class.isAssignableFrom(beanClass);
    if (retVal && this.logger.isTraceEnabled()) {
        this.logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
    }

    return retVal;
}

2.2.2 获取spring 中所有的Advisor 与正在创建的bean 进行类和方法的匹配:

AbstractAdvisorAutoProxyCreator 下getAdvicesAndAdvisorsForBean 方法,匹配当前正在创建的bean 进而判断改bean 是否需要增加代理逻辑

@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	// 获取代理的逻辑对象
    List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
    return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}

向下调用:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	// 获取代理的逻辑对象
	// 获取所有的advisor
    List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
	// 对advisor 进行筛选 对bean 的类型和 类中的所有方法,通过遍历的方式 
	// 依此和bean 类中的方法进行匹配,继而筛选出匹配的代理逻辑对象 advisor
    List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    this.extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
		// 对Advisor 进行排序,AspectJAwareAdvisorAutoProxyCreator 下的 sortAdvisors 对匹配改bean 的所有advisor 进行排序
		// 方法 this.sortAdvisors(eligibleAdvisors) 是在 findEligibleAdvisors 方法流程中的一个步骤。
		// 它将对找到的所有合适的advisor进行排序。排序的目的是为了确定通知(advice)的执行顺序。当存在多个advisor时,
		// 它们定义的通知(如前置通知、后置通知等)可能会冲突或有特定的调用顺序要求。这个排序过程就是确保通知按照预定的顺序执行。
		// 通常基于通知类型、优先级、切入点表达式等规则来决定每个advisor的顺序。

// 排序之后的advisor列表将被用来创建代理,每次方法调用时都会遵守这个确定的顺序来调用各个通知。

// 具体地,排序过程会依据 Advisor 接口或其实现子类的 getOrder 方法返回的值。这个值表明了执行顺序的优先级。
// 数字越低,优先级越高,意味着该advisor的通知将会优先于其他优先级高的advisor执行。
        eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
    }

    return eligibleAdvisors;
}
2.2.2.1 findCandidateAdvisors 获取所有的Advisor:

AnnotationAwareAspectJAutoProxyCreator 下 findCandidateAdvisors 方法获取项目中所有的Advisor 对象:

protected List<Advisor> findCandidateAdvisors() {
	// 通过spring 工厂获取获取所有的advisor类型的bean
    List<Advisor> advisors = super.findCandidateAdvisors();
    if (this.aspectJAdvisorsBuilder != null) {
		// 解析@Aspect 中定义的方法 
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }

    return advisors;
}

aspectJAdvisorsBuilder.buildAspectJAdvisors() 解析@Aspect:

public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;
    if (aspectNames == null) {
        synchronized(this) {
            aspectNames = this.aspectBeanNames;
            if (aspectNames == null) {
                List<Advisor> advisors = new ArrayList();
                List<String> aspectNames = new ArrayList();
				// 获取所有的bean
                String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
                String[] var18 = beanNames;
                int var19 = beanNames.length;

                for(int var7 = 0; var7 < var19; ++var7) {
                    String beanName = var18[var7];
// 
                    if (this.isEligibleBean(beanName)) {
						// 获取bean 的类型
                        Class<?> beanType = this.beanFactory.getType(beanName, false);
                        if (beanType != null && this.advisorFactory.isAspect(beanType)) {
							// 如果这个bean 是@Aspect 切面bean
                            aspectNames.add(beanName);
							// 获取@Aspect 切面bean 的元数据
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

                                MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
								// 获取改切面下所有的advisor
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                                    this.advisorsCache.put(beanName, classAdvisors);
                                } else {
                                    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();
    } else {
        List<Advisor> advisors = new ArrayList();
        Iterator var3 = aspectNames.iterator();

        while(var3.hasNext()) {
            String aspectName = (String)var3.next();
            List<Advisor> cachedAdvisors = (List)this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            } else {
                MetadataAwareAspectInstanceFactory factory = (MetadataAwareAspectInstanceFactory)this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }

        return advisors;
    }
}

this.advisorFactory.getAdvisors(factory) 对@Aspect 中的方法进行解析:
ReflectiveAspectJAdvisorFactory 下的getAdvisors

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	// 获取bean 的类型和名称
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    this.validate(aspectClass);
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
    List<Advisor> advisors = new ArrayList();
	// 获取所有的advisor 
    Iterator var6 = this.getAdvisorMethods(aspectClass).iterator();

    while(var6.hasNext()) {
		// 遍历所有方法封装advisor
        Method method = (Method)var6.next();
        Advisor advisor = this.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);
    }

    Field[] var12 = aspectClass.getDeclaredFields();
    int var13 = var12.length;

    for(int var14 = 0; var14 < var13; ++var14) {
        Field field = var12[var14];
        Advisor advisor = this.getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }

    return advisors;
}

this.getAdvisorMethods 获取所有的advisor : this.getAdvisorMethods:获取所有没有加@Pointcut 注解的方法,对于没有@Before
等注解的普通方法也可以拿到

private List<Method> getAdvisorMethods(Class<?> aspectClass) {
    List<Method> methods = new ArrayList();
    ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
    if (methods.size() > 1) {
		// 排序  对多个注解进行排序
        methods.sort(adviceMethodComparator);
    }

    return methods;
}

methods.sort 对于获取到的进行排序:

static {
    adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS.and((method) -> {
        return AnnotationUtils.getAnnotation(method, Pointcut.class) == null;
    });
	// 先按照 注解排序,对于同一个注解按照方法的名字进行排序(字母排序)
    Comparator<Method> adviceKindComparator = new ConvertingComparator(new InstanceComparator(new Class[]{Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}), (method) -> {
        AbstractAspectJAdvisorFactory.AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
        return ann != null ? ann.getAnnotation() : null;
    });
    Comparator<Method> methodNameComparator = new ConvertingComparator(Method::getName);
    adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
}

this.getAdvisor 对切面中的方法封装为Advisor 对象:

@Nullable
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
    this.validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    AspectJExpressionPointcut expressionPointcut = this.getPointcut(candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
	// 如果改方法有@Before 等注解封装,则通过 InstantiationModelAwarePointcutAdvisorImpl 封装advisor
    return expressionPointcut == null ? null : new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

this.getPointcut // 封装Pointcut

@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
	//  当前方法是否有@Before 等的修饰
    AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    } else {
		//  解析表达式 然后封装Pointcut
        AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
        ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
        if (this.beanFactory != null) {
            ajexp.setBeanFactory(this.beanFactory);
        }

        return ajexp;
    }
}

InstantiationModelAwarePointcutAdvisorImpl 封装advisor:

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut, Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    this.declaredPointcut = declaredPointcut;
    this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
    this.methodName = aspectJAdviceMethod.getName();
    this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
    this.aspectJAdviceMethod = aspectJAdviceMethod;
    this.aspectJAdvisorFactory = aspectJAdvisorFactory;
    this.aspectInstanceFactory = aspectInstanceFactory;
    this.declarationOrder = declarationOrder;
    this.aspectName = aspectName;
    if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Pointcut preInstantiationPointcut = Pointcuts.union(aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
        this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
        this.lazy = true;
    } else {
        this.pointcut = this.declaredPointcut;
        this.lazy = false;
		// 对注解的方法进行解析
        this.instantiatedAdvice = this.instantiateAdvice(this.declaredPointcut);
    }

}

对切面的注解方法进行解析:

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return advice != null ? advice : EMPTY_ADVICE;
}
@Nullable
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
//获取切面对象
    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    this.validate(candidateAspectClass);
    AbstractAspectJAdvisorFactory.AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    } else if (!this.isAspect(candidateAspectClass)) {
        throw new AopConfigException("Advice must be declared inside an aspect type: Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]");
    } else {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Found AspectJ method: " + candidateAdviceMethod);
        }

        Object springAdvice;
		// 对切面的方法进行解析
        switch (aspectJAnnotation.getAnnotationType()) {
            case AtPointcut:
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }

                return null;
            case AtAround:
                springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                break;
            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())) {
                    ((AbstractAspectJAdvice)springAdvice).setReturningName(afterReturningAnnotation.returning());
                }
                break;
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing)aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    ((AbstractAspectJAdvice)springAdvice).setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            default:
                throw new UnsupportedOperationException("Unsupported advice type on method: " + candidateAdviceMethod);
        }

        ((AbstractAspectJAdvice)springAdvice).setAspectName(aspectName);
        ((AbstractAspectJAdvice)springAdvice).setDeclarationOrder(declarationOrder);
        String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
        if (argNames != null) {
            ((AbstractAspectJAdvice)springAdvice).setArgumentNamesFromStringArray(argNames);
        }

        ((AbstractAspectJAdvice)springAdvice).calculateArgumentBindings();
        return (Advice)springAdvice;
    }
}
2.2.2.2 findAdvisorsThatCanApply 对找到的Advisor 进行筛选:
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
   ProxyCreationContext.setCurrentProxiedBeanName(beanName);

    List var4;
    try {
    	// 对正在创建的bean 进行advisor 的匹配,返回 匹配到的Advisor,beanClass 为正在创建bean 的class 类型
        var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    } finally {
        ProxyCreationContext.setCurrentProxiedBeanName((String)null);
    }

    return var4;
}

AopUtils.findAdvisorsThatCanApply 对spring 中已经存在的Advisor 进行匹配:

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
  if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    } else {
        List<Advisor> eligibleAdvisors = new ArrayList();
        Iterator var3 = candidateAdvisors.iterator();

        while(var3.hasNext()) {
            Advisor candidate = (Advisor)var3.next();
            // 通过  canApply 进行匹配 匹配通过放入到eligibleAdvisors 集合中
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }

        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        Iterator var7 = candidateAdvisors.iterator();

        while(var7.hasNext()) {
            Advisor candidate = (Advisor)var7.next();
            if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }

        return eligibleAdvisors;
    }
}

canApply 匹配:

public static boolean canApply(Advisor advisor, Class<?> targetClass) {
return canApply(advisor, targetClass, false);
}

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
 if (advisor instanceof IntroductionAdvisor) {
     return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
 } else if (advisor instanceof PointcutAdvisor) {
     PointcutAdvisor pca = (PointcutAdvisor)advisor;
     return canApply(pca.getPointcut(), targetClass, hasIntroductions);
 } else {
     return true;
 }
 public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  Assert.notNull(pc, "Pointcut must not be null");
  	// 首先对正在创建的bean 的 类型做匹配
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    } else {
    	// 类型匹配完成,则进行方法的匹配
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        if (methodMatcher == MethodMatcher.TRUE) {
            return true;
        } else {
            IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
            if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
            }

            Set<Class<?>> classes = new LinkedHashSet();
            if (!Proxy.isProxyClass(targetClass)) {
                classes.add(ClassUtils.getUserClass(targetClass));
            }

            classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
            Iterator var6 = classes.iterator();

            while(var6.hasNext()) {
                Class<?> clazz = (Class)var6.next();
                // 获取改类的所有方法 
                Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                Method[] var9 = methods;
                int var10 = methods.length;

                for(int var11 = 0; var11 < var10; ++var11) {
                    Method method = var9[var11];
                    if (introductionAwareMethodMatcher != null) {
                    	// 遍历每个方法对当前传入的 advisor 进行匹配 
                        if (introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) {
                            return true;
                        }
                    } else if (methodMatcher.matches(method, targetClass)) {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
    

至此为当前正在创建的bean 筛选出匹配改bean 的所有advisor ;

2.2.3 this.createProxy 创建代理对象:

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 proxyFactory = new ProxyFactory();
    proxyFactory.copyFrom(this);
    if (proxyFactory.isProxyTargetClass()) {
        if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
            Class[] var6 = beanClass.getInterfaces();
            int var7 = var6.length;

            for(int var8 = 0; var8 < var7; ++var8) {
                Class<?> ifc = var6[var8];
                proxyFactory.addInterface(ifc);
            }
        }
    } else if (this.shouldProxyTargetClass(beanClass, beanName)) {
        proxyFactory.setProxyTargetClass(true);
    } else {
        this.evaluateProxyInterfaces(beanClass, proxyFactory);
    }
	// 获取代理逻辑
    Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
	// 设置被代理的对象
    proxyFactory.setTargetSource(targetSource);
    this.customizeProxyFactory(proxyFactory);
    proxyFactory.setFrozen(this.freezeProxy);
    if (this.advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    ClassLoader classLoader = this.getProxyClassLoader();
    if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
        classLoader = ((SmartClassLoader)classLoader).getOriginalClassLoader();
    }
	// 返回代理对象,最终代理对象,则最终执行被代理对象的方法时,对advisors 
	// 完成类和方法的筛选,进入到代理的逻辑
    return proxyFactory.getProxy(classLoader);
}

三、扩展:

spring 中 aop 的 aspect 与aspect jar 包中的aspect 关系:

spring 仅仅使用了aspect 中的一些注解类;在aspect 中对aop 的支持是在代码编译期时就完成了代理逻辑的增强;
在spirng 中虽然使用aspect 的一些注解,但是注解 功能的具体实现时由spring 自身完成的;
在spring中为已经存在的bean 增加 @Aspect 注解后,他的解析过程为:首先这个类是一个bean ,在扫描这个bean 的时候发现它又是一个aspect 则通过特有的bean 对其中定义的方法件解析;将一个个表达式定义成为 pointCunt将注解定义的方法定义成为一个个advice ;进而完成代理逻辑的绑定;


总结

在Spring AOP(面向切面编程)中,AbstractAdvisorAutoProxyCreator 是自动代理创建器的一个抽象类,其主要职责是扫描Spring容器中的Bean,寻找那些需要创建代理对象的Bean(被称为advised bean),并为它们自动生成代理。

在创建代理时,AbstractAdvisorAutoProxyCreator 需要确定应用于每个Bean的通知(advice)和切面(aspect)。在这个过程中,findEligibleAdvisors 方法扮演了关键角色。这个方法负责寻找所有合适的advisor(即包含通知和切入点的对象)。一旦找到这些advisor,它们就可以被用来为目标Bean创建代理,并且在调用Bean的方法时执行相关的通知。

方法 this.sortAdvisors(eligibleAdvisors) 是在 findEligibleAdvisors 方法流程中的一个步骤。它将对找到的所有合适的advisor进行排序。排序的目的是为了确定通知(advice)的执行顺序。当存在多个advisor时,它们定义的通知(如前置通知、后置通知等)可能会冲突或有特定的调用顺序要求。这个排序过程就是确保通知按照预定的顺序执行。通常基于通知类型、优先级、切入点表达式等规则来决定每个advisor的顺序。排序之后的advisor列表将被用来创建代理,每次方法调用时都会遵守这个确定的顺序来调用各个通知。

具体地,排序过程会依据 Advisor 接口或其实现子类的 getOrder 方法返回的值。这个值表明了执行顺序的优先级。数字越低,优先级越高,意味着该advisor的通知将会优先于其他优先级高的advisor执行。

以上为spring 中为bean 增加切面逻辑的整体流程方法,具体的实现细节可以在项目里通过断点进行调试。

文章来源:https://blog.csdn.net/l123lgx/article/details/134802778
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。