spring aop 中次要的主件次要分为以下几个局部:

  1. advisorCreator 继承 spring ioc的扩大接口 beanPostProcessor,次要用来扫描获取 advisor;
  2. advisor spring aop 参谋的意思,封装了spring aop中的切点和告诉;
  3. advice spring aop 的切点,即aop的加强办法;

    springBoot aop 的入口在 AopAutoConfiguration 这个类中,因为springBoot的主动拆卸中,是开启aop的,即spring.aop.auto=true,同样默认配置proxy-target-class的至为true,因而默认应用cglib来做动静代理。

@Configuration(proxyBeanMethods = false)  @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)  public class AopAutoConfiguration {       @Configuration(proxyBeanMethods = false)     @ConditionalOnClass(Advice.class)     static class AspectJAutoProxyingConfiguration {          @Configuration(proxyBeanMethods = false)        @EnableAspectJAutoProxy(proxyTargetClass = false)        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",              matchIfMissing = false)        static class JdkDynamicAutoProxyConfiguration {          }          @Configuration(proxyBeanMethods = false)        @EnableAspectJAutoProxy(proxyTargetClass = true)        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",              matchIfMissing = true)        static class CglibAutoProxyConfiguration {          }       }      }

跟进 @EnableAspectJAutoProxy 这个标签:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(AspectJAutoProxyRegistrar.class)public @interface EnableAspectJAutoProxy {    /**     * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed     * to standard Java interface-based proxies. The default is {@code false}.     */    boolean proxyTargetClass() default false;    /**     * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}     * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.     * Off by default, i.e. no guarantees that {@code AopContext} access will work.     * @since 4.3.1     */    boolean exposeProxy() default false;}

咱们能够看到往ioc容器中注入了一个AspectJAutoProxyRegistrar的类,跟进之,咱们能够看到调用了AopConfigUtil的registerAspectJAnnotationAutoProxyCreatorIfNecessary办法,持续跟进咱们能够看到:往容器外面注入了一个AnnotationAwareAspectJAutoProxyCreator的bean。

@Nullable  public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(        BeanDefinitionRegistry registry, @Nullable Object source) {       return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);  }

此外,AnnotationAwareAspectJAutoProxyCreator 的父类实现了 BeanFactoryAware 接口,在该办法中会调用其的 initBeanFactory 办法,如下:次要是实例化了 AnnotationAwareAspectJAutoProxyCreator 中的aspectJAdvisorsBuilder 属性,该属性提供了后续的advisor的创立工作。

@Override  protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {     super.initBeanFactory(beanFactory);     if (this.aspectJAdvisorFactory == null) {        this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);     }     this.aspectJAdvisorsBuilder =           new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);  }

因为 AnnotationAwareAspectJAutoProxyCreator 实现了 Spring 的后置处理器,而 PointcutAdvisor 创立是在其的 postProcessBeforeInstantiation 的办法中:

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {        Object cacheKey = getCacheKey(beanClass, beanName);        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {            if (this.advisedBeans.containsKey(cacheKey)) {                return null;            }            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {                this.advisedBeans.put(cacheKey, Boolean.FALSE);                return null;            }        }        // 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.        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);        if (targetSource != null) {            if (StringUtils.hasLength(beanName)) {                this.targetSourcedBeans.add(beanName);            }            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);            this.proxyTypes.put(cacheKey, proxy.getClass());            return proxy;        }        return null;    }

这里的 isInfrastructureClass 办法次要是判断以后bean是否是 PointCut, Advice等aop相干的类,如果是的话则该bean不能被代理。再来看下 shouldSkip 办法,改办法中蕴含了 adivor的创立:

protected boolean shouldSkip(Class<?> beanClass, String beanName) {     // TODO: Consider optimization by caching the list of the aspect names   List<Advisor> candidateAdvisors = findCandidateAdvisors();     for (Advisor advisor : candidateAdvisors) {        if (advisor instanceof AspectJPointcutAdvisor &&              ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {           return true;        }     }     return super.shouldSkip(beanClass, beanName);  }

跟进 findCandidateAdvisors 办法,这里次要看 aspectJAdvisorsBuilder 的 buildAspectJAdvisors 办法

@Override  protected List<Advisor> findCandidateAdvisors() {     // Add all the Spring advisors found according to superclass rules.   List<Advisor> advisors = super.findCandidateAdvisors();     // Build Advisors for all AspectJ aspects in the bean factory.   if (this.aspectJAdvisorsBuilder != null) {        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());     }     return advisors;  }

该办法中有个判断条件 this.advisorFactory.isAspect(beanType) 判断该 bean 是否打了 @Aspect 标签,再去做生成 advisor 的操作。这里会调用 advisorFactory 的 getAdvisors 办法。获取到advisors后并把之放入advisorsCache 的缓存中。跟进 getAdvisors 办法:

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<>();              String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(                    this.beanFactory, Object.class, true, false);              for (String beanName : beanNames) {                 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. Class<?> beanType = this.beanFactory.getType(beanName);                 if (beanType == null) {                    continue;                 }                 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);                       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();     }     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;  }

这里的 getAdvisorMethods 办法获取了该类中除打了 @PointCut 的办法,而后依据 getAdvisor 办法获取 advisor,跟进之

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {     Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();     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<>();     for (Method method : getAdvisorMethods(aspectClass)) {        // Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect   // to getAdvisor(...) to represent the "current position" in the declared methods list. // However, since Java 7 the "current position" is not valid since the JDK no longer // returns declared methods in the order in which they are declared in the source code. // Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods // discovered via reflection in order to support reliable advice ordering across JVM launches. // Specifically, a value of 0 aligns with the default value used in // AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor). Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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.   for (Field field : aspectClass.getDeclaredFields()) {        Advisor advisor = getDeclareParentsAdvisor(field);        if (advisor != null) {           advisors.add(advisor);        }     }       return advisors;  }

咱们能够看到返回了一个 InstantiationModelAwarePointcutAdvisorImpl 的 bean,而在该 bean 的结构器中会调用 aspectJAdvisorFactory 的 getAdvice 的办法从而获取 Advice:

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,        int declarationOrderInAspect, String aspectName) {       validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());       AspectJExpressionPointcut expressionPointcut = getPointcut(           candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());     if (expressionPointcut == null) {        return null;     }       return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,           this, aspectInstanceFactory, declarationOrderInAspect, aspectName);  }

依据办法上的标签类型来确定告诉的类型。

    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;    }

生成参谋和告诉之后,下一步就是创立代理类了, springBoot 默认采纳cglib来创立动静代理,代理类的创立在 spring 后置处理器的 postProcessAfterInitialization 中实现:

    @Override    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {        if (bean != null) {            Object cacheKey = getCacheKey(bean.getClass(), beanName);            if (this.earlyProxyReferences.remove(cacheKey) != bean) {                return wrapIfNecessary(bean, beanName, cacheKey);            }        }        return bean;    }

跟进 wrapIfNecessary 办法,重点看 getAdvicesAndAdvisorsForBean 办法,该办法是获取 bean 的告诉和加强办法,如果一个都没找到,间接返回 bean, 只有找到,就创立代理对象。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {     if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {        return bean;     }     if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {        return bean;     }     if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {        this.advisedBeans.put(cacheKey, Boolean.FALSE);        return bean;     }       // Create proxy if we have advice.   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);     if (specificInterceptors != DO_NOT_PROXY) {        this.advisedBeans.put(cacheKey, Boolean.TRUE);        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;  }

跟进 getAdvicesAndAdvisorsForBean 办法,其中要害办法为 findEligibleAdvisors,这里的 findCandidateAdvisors 能够从缓存中失去之前创立的 advisor。而 findAdvisorsThatCanApply 办法则是为 bean 寻找相匹配的告诉和加强办法,跟进之。

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {        List<Advisor> candidateAdvisors = findCandidateAdvisors();        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);        extendAdvisors(eligibleAdvisors);        if (!eligibleAdvisors.isEmpty()) {            eligibleAdvisors = sortAdvisors(eligibleAdvisors);        }        return eligibleAdvisors;    }

持续跟进会进入 AopUtil 的 findAdvisorsThatCanApply 办法:

    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) {            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;    }

该办法中会调用 canApply 办法去判断 advisor 和以后的 bean 是否匹配:

    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 {            // It doesn't have a pointcut so we assume it applies.            return true;        }    }

因为咱们之前创立的 advvisor 为 InstantiationModelAwarePointcutAdvisorImpl, 该类实现了 PointcutAdvisor 接口,这里走 canApply 办法:

    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) {            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;    }

具体的匹配比较复杂,在SignaturePattern 中的 matchesExactlyMethod 中对代理的办法做了匹配。

    private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) {        if (parametersCannotMatch(aMethod)) {            // System.err.println("Parameter types pattern " + parameterTypes + " pcount: " + aMethod.getParameterTypes().length);            return FuzzyBoolean.NO;        }        // OPTIMIZE only for exact match do the pattern match now? Otherwise defer it until other fast checks complete?        if (!name.matches(aMethod.getName())) {            return FuzzyBoolean.NO;        }        // Check the throws pattern        if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) {            return FuzzyBoolean.NO;        }        // '*' trivially matches everything, no need to check further        if (!declaringType.isStar()) {            if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) {                return FuzzyBoolean.MAYBE;            }        }        // '*' would match any return value        if (!returnType.isStar()) {            boolean b = returnType.isBangVoid();            if (b) {                String s = aMethod.getReturnType().getSignature();                if (s.length() == 1 && s.charAt(0) == 'V') {                    // it is void, so not a match                    return FuzzyBoolean.NO;                }            } else {                if (returnType.isVoid()) {                    String s = aMethod.getReturnType().getSignature();                    if (s.length() != 1 || s.charAt(0) != 'V') {                        // it is not void, so not a match                        return FuzzyBoolean.NO;                    }                } else {                    if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) {                        // looking bad, but there might be parameterization to consider...                        if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) {                            // ok, it's bad.                            return FuzzyBoolean.MAYBE;                        }                    }                }            }        }        // The most simple case: pattern is (..) will match anything        if (parameterTypes.size() == 1 && parameterTypes.get(0).isEllipsis()) {            return FuzzyBoolean.YES;        }        if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) {            return FuzzyBoolean.NO;        }        // OPTIMIZE both resolution of these types and their annotations should be deferred - just pass down a world and do it lower        // down        // ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());        ResolvableTypeList rtl = new ResolvableTypeList(world, aMethod.getParameterTypes());        // Only fetch the parameter annotations if the pointcut is going to be matching on them        ResolvedType[][] parameterAnnotationTypes = null;        if (isMatchingParameterAnnotations()) {            parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();            if (parameterAnnotationTypes != null && parameterAnnotationTypes.length == 0) {                parameterAnnotationTypes = null;            }        }        if (!parameterTypes.matches(rtl, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {            // It could still be a match based on the generic sig parameter types of a parameterized type            if (!parameterTypes.matches(new ResolvableTypeList(world, aMethod.getGenericParameterTypes()), TypePattern.STATIC,                    parameterAnnotationTypes).alwaysTrue()) {                return FuzzyBoolean.MAYBE;                // It could STILL be a match based on the erasure of the parameter types??                // to be determined via test cases...            }        }        // check that varargs specifications match        if (!matchesVarArgs(aMethod, world)) {            return FuzzyBoolean.MAYBE;        }        // passed all the guards..        return FuzzyBoolean.YES;    }

获取到 aop 的拦挡办法之后调用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 = new ProxyFactory();        proxyFactory.copyFrom(this);        if (!proxyFactory.isProxyTargetClass()) {            if (shouldProxyTargetClass(beanClass, beanName)) {                proxyFactory.setProxyTargetClass(true);            }            else {                evaluateProxyInterfaces(beanClass, proxyFactory);            }        }        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);        proxyFactory.addAdvisors(advisors);        proxyFactory.setTargetSource(targetSource);        customizeProxyFactory(proxyFactory);        proxyFactory.setFrozen(this.freezeProxy);        if (advisorsPreFiltered()) {            proxyFactory.setPreFiltered(true);        }        return proxyFactory.getProxy(getProxyClassLoader());    }

持续跟进 getProxy 会进入到 DefaultProsyFactory 的 createAopProxy 办法,这里能够看到应用jdk动静代理还是应用cglib作为动静代理的判断条件

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {            Class<?> targetClass = config.getTargetClass();            if (targetClass == null) {                throw new AopConfigException("TargetSource cannot determine target class: " +                        "Either an interface or a target is required for proxy creation.");            }            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {                return new JdkDynamicAopProxy(config);            }            return new ObjenesisCglibAopProxy(config);        }        else {            return new JdkDynamicAopProxy(config);        }    }

动静代理的调用,这里以cglib做示例:当执行被代理对象的业务办法时,会执行 CglibAopProxy 的 intercept 办法:

            Object oldProxy = null;            boolean setProxyContext = false;            Object target = null;            TargetSource targetSource = this.advised.getTargetSource();            try {                if (this.advised.exposeProxy) {                    // Make invocation available if necessary.                    oldProxy = AopContext.setCurrentProxy(proxy);                    setProxyContext = true;                }                // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...                target = targetSource.getTarget();                Class<?> targetClass = (target != null ? target.getClass() : null);                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);                Object retVal;                // Check whether we only have one InvokerInterceptor: that is,                // no real advice, but just reflective invocation of the target.                if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {                    // We can skip creating a MethodInvocation: just invoke the target directly.                    // Note that the final invoker must be an InvokerInterceptor, so we know                    // it does nothing but a reflective operation on the target, and no hot                    // swapping or fancy proxying.                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);                    retVal = methodProxy.invoke(target, argsToUse);                }                else {                    // We need to create a method invocation...                    retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();                }                retVal = processReturnType(proxy, target, method, retVal);                return retVal;            }            finally {                if (target != null && !targetSource.isStatic()) {                    targetSource.releaseTarget(target);                }                if (setProxyContext) {                    // Restore old proxy.                    AopContext.setCurrentProxy(oldProxy);                }            }        }

这里的 getInterceptorsAndDynamicInterceptionAdvice 办法通过 Advice 获取到对应测加强办法,如果缓存中没有 CglibMethodInvocation 的对象的话,就new了一个并执行他的 proceed 办法。跟进进入 ReflectiveMethodInvocation 的 proceed 办法。

public Object proceed() throws Throwable {        // We start with an index of -1 and increment early.        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {            return invokeJoinpoint();        }        Object interceptorOrInterceptionAdvice =                this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {            // Evaluate dynamic method matcher here: static part will already have            // been evaluated and found to match.            InterceptorAndDynamicMethodMatcher dm =                    (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;            Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());            if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {                return dm.interceptor.invoke(this);            }            else {                // Dynamic matching failed.                // Skip this interceptor and invoke the next in the chain.                return proceed();            }        }        else {            // It's an interceptor, so we just invoke it: The pointcut will have            // been evaluated statically before this object was constructed.            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);        }    }

这里的 currentInterceptorIndex 记录加强办法的索引,从-1开始,没执行一个加强办法该值加1, 加强办法执行之后持续调用这个 proceed 办法,直到最初一个加强办法被执行,之后执行被代理办法。然而对于After告诉类型的加强办法并没有马上执行,而是写在了 finally 块中: