本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。在阅读过程中也创建了一些衍生文章,衍生文章的意义是因为自己在看源码的过程中,部分知识点并不了解或者对某些知识点产生了兴趣,所以为了更好的阅读源码,所以开设了衍生篇的文章来更好的对这些知识点进行进一步的学习。
全集目录:Spring源码分析:全集整理
本文系列: Spring源码分析十一:@Aspect方式的AOP上篇 - @EnableAspectJAutoProxy Spring源码分析十二:@Aspect方式的AOP中篇 - getAdvicesAndAdvisorsForBean Spring源码分析十三:@Aspect方式的AOP下篇 - createProxy
本文衍生篇: Spring 源码分析衍生篇九 : AOP源码分析 - 基础篇
这个方法的实现在 AbstractAdvisorAutoProxyCreator 类中。getAdvicesAndAdvisorsForBean 的作用是获取所有适用于当前Bean 的 Advisors 。因为并不是所有的规则都适用于当前bean,所有会有一个筛选的过程。
这个方法的逻辑分为两步:
寻找所有的顾问(Advisors), 这个方法在Aop中被重写了,为了可以的动态生成 Advisor – findCandidateAdvisors寻找所有顾问(Advisors) 中适用于bean 的增强并应用 – findAdvisorsThatCanApply @Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { // 主要逻辑还是在 findEligibleAdvisors 中完成。 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); //如果没有增强点则不需要代理。 if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); } ... protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { // 寻找所有的增强 List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 寻找所有增强中适用于bean 的增强并应用 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }可以看到两个核心方法 findCandidateAdvisors 和 findAdvisorsThatCanApply 。下面我们一个一个来分析。
前文讲过,Spring aop 注入的自动代理创建器是 AnnotationAwareAspectJAutoProxyCreator,所以AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors 的代码如下:
@Override protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. // 1. 这里是从BeanFactory 中找出来 所有 Advisor 类型的bean。即找到所有配置的Advisor。 List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { // 2. buildAspectJAdvisors() 从代码中动态找到了需要的增强点 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }这里来解释一下这两个方法的区别:
super.findCandidateAdvisors(); : 一般获取的都是通过直接注册的 Advisors。比如事务的顾问,直接通过 @Bean 注入到Spring容器中。 this.aspectJAdvisorsBuilder.buildAspectJAdvisors() : 主要获取我们通过注解方式动态注册的 Advisors。比如 在 Aop 中根据不同的表达式,需要拦截的切面也不同,那就需要为这些切面动态生成 Advisors。而不能直接注入。super.findCandidateAdvisors(); 这里调用的实际上是AbstractAdvisorAutoProxyCreator 中的findCandidateAdvisors 方法。这一步最终会调用如下的findAdvisorBeans 方法。其作用根据注释也能明白。获取所有合格的 Advisor Bean(合格并不代表适用当前bean),忽略了FactoryBean 和创建中的bean。
/** * Find all eligible Advisor beans in the current bean factory, * ignoring FactoryBeans and excluding beans that are currently in creation. * @return the list of {@link org.springframework.aop.Advisor} beans * @see #isEligibleBean */ public List<Advisor> findAdvisorBeans() { // Determine list of advisor bean names, if not cached already. // 从缓存中获取 advisorNames String[] advisorNames = this.cachedAdvisorBeanNames; if (advisorNames == null) { // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the auto-proxy creator apply to them! // 从 Spring 中获取 Advisor 类型的 beanname 。这里获取到的一般都是硬编码注入的 Advisors advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } // 如果没有获取到 Advisors ,直接返回 if (advisorNames.length == 0) { return new ArrayList<>(); } // 到这一步必定有Advisors ,我们需要通过name来获取到bean的实例 List<Advisor> advisors = new ArrayList<>(); for (String name : advisorNames) { if (isEligibleBean(name)) { if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isTraceEnabled()) { logger.trace("Skipping currently created advisor '" + name + "'"); } } else { try { // 根据name 和 类型获取到 Advisor 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()); } // Ignore: indicates a reference back to the bean we're trying to advise. // We want to find advisors other than the currently created bean itself. continue; } } throw ex; } } } } return advisors; }this.aspectJAdvisorsBuilder.buildAspectJAdvisors() 的作用就是 在当前的bean工厂中查找带有AspectJ注解的 Aspect bean,并封装成代表他们的Spring Aop Advisor,注入到Spring 中。
基本的思路如下:
获取所有beanName,这一步所有在beanFactory中注册的bean都会被提取出来遍历所有的beanName, 找出声明AspectJ注解的类,进行进一步处理对标记为AspectJ注解的类进行Advisors 提取将提取的结果保存到缓存中。 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<>(); aspectNames = new ArrayList<>(); // 1. 获取所有的beanName。 String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Object.class, true, false); // 遍历beanname, 找出对应的增强方法 for (String beanName : beanNames) { // 不合法的bean略过,由子类定义规则,默认true if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. // 获取对应bean 的类型 Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } // 2. 如果存在AspectJ 注解,进一步处理 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); // 3. 解析标记AspectJ注解中的增强方法,也就是被 @Before、@Around 等注解修饰的方法,并将其封装成 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 { // Per target or per this. 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(); } // 4. 将所有的增强方法保存到缓存中。 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; }在上述代码中,最为复杂的就是增强器(Advisors)获取,也就是 this.advisorFactory.getAdvisors(factory); 这一步, 具体的实现是在 ReflectiveAspectJAdvisorFactory#getAdvisors中。下面我们具体来看代码
@Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { // 获取标记为 AspectJ 的类 Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass(); // 获取标记为 AspectJ 的名字 String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName(); // 进行验证 validate(aspectClass); // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator // so that it will only instantiate once. MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory = new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory); List<Advisor> advisors = new ArrayList<>(); // 获取 aspectClass 的所有方法,过滤掉了声明为 PointCut 的方法以及 !method.isBridge() && !method.isSynthetic() 的方法 for (Method method : getAdvisorMethods(aspectClass)) { // 将方法封装成 Advisor 。如果不满足封装条件,即没有被 AspectJ 系列注解 Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } // If it's a per target aspect, emit the dummy instantiating aspect. if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) { // 如果寻找的增强器不为空而且有配置了增强延迟初始化,则需要在首位加入同步实例化增强器 Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory); advisors.add(0, instantiationAdvisor); } // Find introduction fields. // 获取 DeclaredParents 注解并处理。@DeclaredParents 注解可以实现指定某些代理类是某些接口的实现。 for (Field field : aspectClass.getDeclaredFields()) { Advisor advisor = getDeclareParentsAdvisor(field); if (advisor != null) { advisors.add(advisor); } } return advisors; } ... // 筛选出合适的方法,并封装成 Advisor 。这里返回的都是 InstantiationModelAwarePointcutAdvisorImpl public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); // 1. 切点信息的获取 AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } // 2. 根据切点信息封装成增强器 return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }这里根据 切点信息来动态生成了增强器,也就是 Advisor。是根据AOP 的注解解析来的动态生成的。 可以看到,封装的关键的操作还是在 getAdvisor 方法 中,下面我们来详细分析:
getPointcut 方法的实现很简单,就是判断方法上是否有 AspectJ系列的注解,有则封装。
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { // 获取方法上的注解,包括 Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); if (aspectJAnnotation == null) { return null; } // 到这里必然有 AspectJ系列的注解了 // 使用 AspectJExpressionPointcut 实例封装获取的信息 AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]); // 提取出的得到的注解中的表达式 // 如 @Pointcut("execution(* com.kingfish.aopdemo.controller.AopController.hello(String))") 中的 execution(* com.kingfish.aopdemo.controller.AopController.hello(String)) ajexp.setExpression(aspectJAnnotation.getPointcutExpression()); if (this.beanFactory != null) { ajexp.setBeanFactory(this.beanFactory); } return ajexp; }其中 AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); 方法如下:
private static final Class<?>[] ASPECTJ_ANNOTATION_CLASSES = new Class<?>[] { Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class}; // 获取指定方法上的注解并使用 AspectJAnnotation 封装 protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { for (Class<?> clazz : ASPECTJ_ANNOTATION_CLASSES) { AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) clazz); if (foundAnnotation != null) { return foundAnnotation; } } return null; }在 Aop 中所有的增强都由 Advisor 的实现类 InstantiationModelAwarePointcutAdvisorImpl 统一封装。
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()) { // Static part of the pointcut is a lazy type. Pointcut preInstantiationPointcut = Pointcuts.union( aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); // Make it dynamic: must mutate from pre-instantiation to post-instantiation state. // If it's not a dynamic pointcut, it may be optimized out // by the Spring AOP infrastructure after the first evaluation. this.pointcut = new PerTargetInstantiationModelPointcut( this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory); this.lazy = true; } else { // A singleton aspect. this.pointcut = this.declaredPointcut; this.lazy = false; this.instantiatedAdvice = 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); }在封装过程中只是简单的将信息封装在类的实例中,所有的信息只是单纯的赋值,在实例化过程中还完成了对于增强器的处理。因为不同的增强体现的逻辑是不同的,简单来说就是不同的切点信息的动作是不同的,比如 @Before 和 @After 注解的动作就不同, @Before 需要在切点方法前调用, @After 需要在切点方法后调用 。而根据注解中的信息初始化对应的增强器就是在instantiateAdvice 中实现。而instantiateAdvice 中主要还是调用了 this.aspectJAdvisorFactory.getAdvice,因此我们来看 this.aspectJAdvisorFactory.getAdvice 的代码:
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); if (aspectJAnnotation == null) { return null; } // If we get here, we know we have an AspectJ method. // Check that it's an AspectJ-annotated class if (!isAspect(candidateAspectClass)) { throw new AopConfigException("Advice must be declared inside an aspect type: " + "Offending method '" + candidateAdviceMethod + "' in class [" + candidateAspectClass.getName() + "]"); } if (logger.isDebugEnabled()) { logger.debug("Found AspectJ method: " + 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; 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; }可以看到,Spring会根据不同的注解生成不同的增强器(通知)。比如 AspectJAroundAdvice、AspectJMethodBeforeAdvice 等,从而完成不同的注解所需的动作。
经历了第一步,也仅仅是将所有的顾问(Advisors),也就是增强器,全部查找出来。但是并非所有的Advisors 都适用于当前bean。所以这一步的目的是为了过滤出适合当前bean的增强器。
protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }可以看到关键内容还是在 AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); 所以我们继续往下看。AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); 的代码如下:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); // 首先处理引介增强 for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { // 引介增强已处理 if (candidate instanceof IntroductionAdvisor) { // already processed continue; } // 对于普通bean 的处理 if (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) { // 基础篇曾介绍过,IntroductionAdvisor 和 PointcutAdvisor 的区别在于 PointcutAdvisor 的切入点更细。我们这里的Advisor都是PointcutAdvisor 类型 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 { // It doesn't have a pointcut so we assume it applies. return true; } } .... 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(); if (methodMatcher == MethodMatcher.TRUE) { // No need to iterate the methods if we're matching any method anyway... return true; } 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)); for (Class<?> clazz : classes) { // 获取当前bean的所有方法 Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { // 在这里判断方法是否匹配 if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false; }从上面我们可以看到 Pointcut 匹配的需要满足下面两个条件:
pc.getClassFilter().matches(targetClass) 返回truepc.getMethodMatcher().matches(method, targetClass) 返回truegetAdvicesAndAdvisorsForBean 方法的作用就是筛选出适用于当前bean的Advisor。 简单来说就是两步
super.findCandidateAdvisors(); 挑选出所有的 Advisor。包括编码注入的和动态封装的findAdvisorsThatCanApply 通过 Advisor 中的Pointcut 筛选出适合当前bean的 Advisor。以上:内容部分参考 《Spring实战》 《Spring源码深度解析》 https://www.cnblogs.com/cheng21553516/p/12190008.html https://blog.csdn.net/wyl6019/article/details/80136000 如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正