上一步得到增强后,需要根据 bean 过滤下,得到当前 bean 可用的增强。

    1. protected List<Advisor> findAdvisorsThatCanApply(
    2. List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    3. ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    4. try {
    5. return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    6. } finally {
    7. ProxyCreationContext.setCurrentProxiedBeanName(null);
    8. }
    9. }

    来到方法 AopUtils#findAdvisorsThatCanApply

    1. public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    2. if (candidateAdvisors.isEmpty()) {
    3. return candidateAdvisors;
    4. }
    5. List<Advisor> eligibleAdvisors = new ArrayList<>();
    6. // 首先处理引介增强
    7. for (Advisor candidate : candidateAdvisors) {
    8. if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
    9. eligibleAdvisors.add(candidate);
    10. }
    11. }
    12. boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    13. for (Advisor candidate : candidateAdvisors) {
    14. if (candidate instanceof IntroductionAdvisor) {
    15. // already processed
    16. continue;
    17. }
    18. // 处理普通的增强
    19. if (canApply(candidate, clazz, hasIntroductions)) {
    20. eligibleAdvisors.add(candidate);
    21. }
    22. }
    23. return eligibleAdvisors;
    24. }
    1. 首先处理引介增强,也就是通过注解 DeclareParents 实现的增强;
    2. 然后再处理普通的增强。

    canApply 判断增强能否应用到该 bean:

    1. public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    2. if (advisor instanceof IntroductionAdvisor) {
    3. return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    4. } else if (advisor instanceof PointcutAdvisor) {
    5. PointcutAdvisor pca = (PointcutAdvisor) advisor;
    6. return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    7. } else {
    8. // It doesn't have a pointcut so we assume it applies.
    9. return true;
    10. }
    11. }

    判断过程:

    1. 如果是引介增强,那么判断下class是否适用;
    2. 如果是普通增强,获取切点信息继续判断;
    3. 如果没有切点,那么认为适用。

    所以引介增强判断和普通增强的判断是分开的,那么普通增强的判断来到重载的方法 canApply

    1. public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    2. Assert.notNull(pc, "Pointcut must not be null");
    3. if (!pc.getClassFilter().matches(targetClass)) {
    4. return false;
    5. }
    6. MethodMatcher methodMatcher = pc.getMethodMatcher();
    7. if (methodMatcher == MethodMatcher.TRUE) {
    8. // No need to iterate the methods if we're matching any method anyway...
    9. return true;
    10. }
    11. IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    12. if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
    13. introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    14. }
    15. Set<Class<?>> classes = new LinkedHashSet<>();
    16. if (!Proxy.isProxyClass(targetClass)) {
    17. classes.add(ClassUtils.getUserClass(targetClass));
    18. }
    19. classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    20. for (Class<?> clazz : classes) {
    21. Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
    22. for (Method method : methods) {
    23. if (introductionAwareMethodMatcher != null ?
    24. introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
    25. methodMatcher.matches(method, targetClass)) {
    26. return true;
    27. }
    28. }
    29. }
    30. return false;
    31. }