SpringAOP的简单使用与原理解析

1.SpringAOP的简单使用

1.1引入相关依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>

1.1自定义一个注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface MyAnnotation {
    /**
     * 值
     */
    String value() default "";
}

1.2创建切面

@Aspect
@Component
@Slf4j
public class MyAnnotationAspect {
 
    @Pointcut("@annotation(com.aojie.springbootdemo.annotationAnnotationAwareAspectJAutoProxyCreator .MyAnnotation)")
    public void pointCut() {
    }
 
    @Before("pointCut()")
    public void testBeforeAdvice() {
        log.info("---前置通知---");
    }
 
    @After("pointCut()")
    public void testAfterAdvice() {
        log.info("---后置通知---");
    }
 
    @Around("pointCut()")
    public Object testAroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
        log.info("---环绕通知---");
        return pjp.proceed();
    }
}

1.3使用注解

@Service
@Slf4j
public class TestServiceImpl implements TestService {
    @Override
    @MyAnnotation
    public void testMethod() {
        //业务处理
        log.info("业务逻辑处理");
    }
}

1.4最终效果

在这里插入图片描述

2.原理解析

2.1AOP 基础概念

  • 连接点(Join point):能够被拦截的地方,Spring AOP 是基于动态代理的,所以是方法拦截的,每个成员方法都可以称之为连接点;
  • 切点(Poincut):每个方法都可以称之为连接点,我们具体定位到某一个方法就成为切点;(where 在哪里做)
  • 增强/通知(Advice):表示添加到切点的一段逻辑代码,并定位连接点的方位信息;(when 方法执行前后 what 做什么)
  • 织入(Weaving):将增强/通知添加到目标类的具体连接点上的过程;(把切面加入到对象,并创建出代理对象的过程)
  • 切面(Aspect):切面由切点和增强/通知组成,它既包括了横切逻辑的定义、也包括了连接点的定义。(切点+通知 什么时机什么地方做什么)

2.2AOP的入口

通过@EnableAspectJAutoProxy注解开启AOP

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

重点在于@Import(AspectJAutoProxyRegistrar.class)这一行(@import注解详解),简单来说就是会引入AspectJAutoProxyRegistrar这个类并调用其registerBeanDefinitions方法

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
 
    @Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //往容器中注册AnnotationAwareAspectJAutoProxyCreator
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
 
        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
 
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, 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(AUTO_PROXY_CREATOR_BEAN_NAME)) {
       BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
       if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
          int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
          int requiredPriority = findPriorityForClass(cls);
          if (currentPriority < requiredPriority) {
             apcDefinition.setBeanClassName(cls.getName());
          }
       }
       return null;
    }
    //注册AnnotationAwareAspectJAutoProxyCreator beanDefinition
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

总结一下:@EnableAspectJAutoProxy注解就是往spring容器注册一个AnnotationAwareAspectJAutoProxyCreator这个bean,那么这个bean有什么用呢?我们后面再说。
这里可能有的同学就会问了,我们的服务里面没有使用@EnableAspectJAutoProxy这个注解,却也能使用AOP,是为什么呢?

这里可能有的同学就会问了,我们的服务里面没有使用@EnableAspectJAutoProxy这个注解,却也能使用AOP,是为什么呢?
这是因为spring-boot-autoconfigure这个包将AopAutoConfiguration自动装配进来了
在这里插入图片描述

@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")
        static class JdkDynamicAutoProxyConfiguration {
 
        }
 
        //默认加载这个
        @Configuration(proxyBeanMethods = false)
        @EnableAspectJAutoProxy(proxyTargetClass = true)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
                matchIfMissing = true)
        static class CglibAutoProxyConfiguration {
 
        }
 
    }
}

2.3前置处理

现在就来说说AnnotationAwareAspectJAutoProxyCreator,先来看下它的结构
在这里插入图片描述
AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor和BeanPostProcessor接口,这两个接口的作用是在bean的实例化前后和初始化前后做一些处理。那就来看下它都做了些什么,先来看下它实例化前都做了些什么。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport  implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        //获取缓存的key 一般就是beanName
        Object cacheKey = getCacheKey(beanClass, beanName);
 
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //是否已经处理过
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            //是否基础设施类或者是否可以跳过 *shouldSkip是重点
            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;
    }
...
}

前置处理的重点在于shouldSkip(beanClass, beanName)这个方法

public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
...
    @Override
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        //获取所有的Advisor通知器
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }
...
}

List candidateAdvisors = findCandidateAdvisors();

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
...
 
    @Override
    protected List<Advisor> findCandidateAdvisors() {
        //获取所有实现Advisor接口的类
        List<Advisor> advisors = super.findCandidateAdvisors();
        if (this.aspectJAdvisorsBuilder != null) {
            //获取切面配置的Advisor *重点
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
...
}

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

public class BeanFactoryAspectJAdvisorsBuilder {
...
    public List<Advisor> buildAspectJAdvisors() {
        //切面的beanName 做了缓存
        List<String> aspectNames = this.aspectBeanNames;
 
        //第一次进来为空
        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    //从容器中获取所有的beanName
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    //遍历
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        //获取类对象
                        Class<?> beanType = this.beanFactory.getType(beanName, false);
                        if (beanType == null) {
                            continue;
                        }
                        //是否@Aspect注解标注
                        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;
                }
            }
        }
        //没有@Aspect注解的切面
        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;
    }
...
}

List classAdvisors = this.advisorFactory.getAdvisors(factory);

public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
...
    //排除@Pointcut切入点注解
    private static final MethodFilter adviceMethodFilter = ReflectionUtils.USER_DECLARED_METHODS
            .and(method -> (AnnotationUtils.getAnnotation(method, Pointcut.class) == null));
 
    //通知方法的排序规则
    //1.先按Around, Before, After, AfterReturning, AfterThrowing顺序 再按方法名排序
    private static final Comparator<Method> adviceMethodComparator;
 
    static {
        Comparator<Method> adviceKindComparator = new ConvertingComparator<>(
                new InstanceComparator<>(
                        Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),
                (Converter<Method, Annotation>) method -> {
                    AspectJAnnotation<?> ann = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
                    return (ann != null ? ann.getAnnotation() : null);
                });
        Comparator<Method> methodNameComparator = new ConvertingComparator<>(Method::getName);
        adviceMethodComparator = adviceKindComparator.thenComparing(methodNameComparator);
    }
 
 
   @Override
    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)) {
 
            //根据方法获取通知器
            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;
    }
 
 
    private List<Method> getAdvisorMethods(Class<?> aspectClass) {
        List<Method> methods = new ArrayList<>();
        //找出除了@Pointcout标注的所有方法
        ReflectionUtils.doWithMethods(aspectClass, methods::add, adviceMethodFilter);
        if (methods.size() > 1) {
            methods.sort(adviceMethodComparator);
        }
        return methods;
    }
 
 
    @Override
    @Nullable
    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);
    }
...
}

在这里插入图片描述

*总结一下:前置处理主要是去获取所有的通知器,主要是实现了Advisor接口的类以及切面中通知方法生成的通知器。

2.4后置处理

说完了前置处理,下面来说一下后置处理,前置处理主要都是一些准备工作,后置处理就是在bean的初始化之后对bean进行拦截并生成代理对象的过程。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
...
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            //获取缓存key 一般就是beanName
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                //包装生成代理类
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return 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;
        }
 
        //获取当前bean的所有通知和通知器 *重点
        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;
    }
...
}

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
...
    @Override
    @Nullable
    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();
    }
 
 
    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;
    }
 
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
 
        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
            //根据切入点表达式找出可用的通知器
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }
...
}

*总结一下:后置处理主要就是在对象实例化之后从所有的通知器中获取可用的通知器,然后创建代理对象。

2.5方法执行

在这里插入图片描述
此时的testService就是一个代理后对象了,进入方法内部看下执行流程

class CglibAopProxy implements AopProxy, Serializable {
...
    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
 
        private final AdvisedSupport advised;
 
        public DynamicAdvisedInterceptor(AdvisedSupport advised) {
            this.advised = advised;
        }
 
        @Override
        @Nullable
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            Object oldProxy = null;
            boolean setProxyContext = false;
            Object target = null;
            //此处是SingletonTargetSource
            TargetSource targetSource = this.advised.getTargetSource();
            try {
                if (this.advised.exposeProxy) {
                    // Make invocation available if necessary.
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }
                //获取代理的目标对象
                target = targetSource.getTarget();
                Class<?> targetClass = (target != null ? target.getClass() : null);
                //获取拦截器链 就是将所有的通知包装成InterceptorAndDynamicMethodMatcher
                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() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
                    // 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 = invokeMethod(target, method, argsToUse, methodProxy);
                }
                else {
                    //入口 包装成CglibMethodInvocation然后执行proceed方法
                    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);
                }
            }
        }
    }
...
}

①new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
...
        @Override
        @Nullable
        public Object proceed() throws Throwable {
            try {
                //调用父类的proceed方法 也就是ReflectiveMethodInvocation类
                return super.proceed();
            }
            catch (RuntimeException ex) {
                throw ex;
            }
            catch (Exception ex) {
                if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
                        KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
                    // Propagate original exception if declared on the target method
                    // (with callers expecting it). Always propagate it for Kotlin code
                    // since checked exceptions do not have to be explicitly declared there.
                    throw ex;
                }
                else {
                    // Checked exception thrown in the interceptor but not declared on the
                    // target method signature -> apply an UndeclaredThrowableException,
                    // aligned with standard JDK dynamic proxy behavior.
                    throw new UndeclaredThrowableException(ex);
                }
            }
        }
...
}

super.proceed();

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
...
    //起始值为-1
    private int currentInterceptorIndex = -1;
 
 
    @Override
    @Nullable
    public Object proceed() throws Throwable {
        //如果是最后一个 就执行目标方法testMethod()
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return invokeJoinpoint();
        }
 
        //++this.currentInterceptorIndex取出拦截器
        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.
            //第一个拦截器是ExposeInvocationInterceptor 它主要的作用是将当前的AOP调用链路暴露出来
            return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
        }
    }
...
}

第一次是进入到ExposeInvocationInterceptor的invoke方法
在这里插入图片描述

public final class ExposeInvocationInterceptor implements MethodInterceptor, PriorityOrdered, Serializable {
...
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        MethodInvocation oldInvocation = invocation.get();
        invocation.set(mi);
        try {
            //又执行CglibMethodInvocation的proceed方法
            return mi.proceed();
        }
        finally {
            invocation.set(oldInvocation);
        }
    }
...
}

mi.proceed()方法执行又回到了①处,此时获取的就是第二个拦截器AspectJAroundAdvice,对应的就是@Around环绕通知
在这里插入图片描述
进入到dm.interceptor.invoke(this)方法

public class AspectJAroundAdvice extends AbstractAspectJAdvice implements MethodInterceptor, Serializable {
...
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        if (!(mi instanceof ProxyMethodInvocation)) {
            throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
        }
        ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi;
        ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
        JoinPointMatch jpm = getJoinPointMatch(pmi);
        //执行通知方法
        return invokeAdviceMethod(pjp, jpm, null, null);
    }
...
}

环绕通知就是直接执行通知方法,也就是@Around注解标注的方法
在这里插入图片描述
方法里面又执行了熟悉的proceed()方法,我们大概就能猜到肯定是又回到①处,再次取出拦截器,根据顺序这次取出的应该就是前置通知了
在这里插入图片描述

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
...
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        //执行通知方法
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        return mi.proceed();
    }
...
}

在这里插入图片描述
在执行完前置通知方法后,又执行了proceed()方法回到①
在这里插入图片描述
此时就是最后一个拦截器AspectJAfterAdvice后置通知

public class AspectJAfterAdvice extends AbstractAspectJAdvice
        implements MethodInterceptor, AfterAdvice, Serializable {
...
    @Override
    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        }
        finally {
            //执行后置通知方法
            invokeAdviceMethod(getJoinPointMatch(), null, null);
        }
    }
...
}

可以看到在后置通知里面是先执行proceed()方法,然后在finally代码块里面执行的后置通知方法。
这一次回到proceed()方法,因为拦截器链都已经执行完了,所以这次就是执行目标方法了
在这里插入图片描述
在方法执行的过程中用到了责任链+递归,看起来可能会有点懵,所以配图一张
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ByLir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值