SpringBoot之@Aspect注解实现AOP源码(整体流程)

用法


导包

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

使用

@Slf4j
@Component("myAop")
@Aspect
public class SunpyAopBean {
 
    @Pointcut("execution(public void com.sunpy.simpleweb.bean.SunpyBean.doPrint())")
    public void cutMethod() {
 
    }
 
    @Before("cutMethod()")
    public void beforeExecute() {
        log.info("================================= beforeExecute");
    }
}

结果

2023-05-07 18:22:13.768  INFO  [http-nio-3800-exec-1] c.s.simpleweb.bean.SunpyAopBean.beforeExecute - ================================= beforeExecute
2023-05-07 18:22:13.779  INFO  [http-nio-3800-exec-1] c.sunpy.simpleweb.bean.SunpyBean.doPrint - ================================= doPrint

流程图


AOP的源码步骤


    1. 通过自动装配,注入一个AnnotationAwareAspectJAutoProxyCreator(这是一个实现了BeanPostProcessor的bean后置处理器),那么生成代理对象的方法在initializeBean方法中实现。
    1. 被代理的原生bean,如果需要aop代理,那么会调用createProxy方法生成代理bean。
    1. 原本应该返回原生bean,那么此时代理bean会替换到原生bean。
    1. 当调用的实现,执行拦截的方法,先获取增强器Advice,然后执行增强的方法,最后再执行被拦截的方法。

SpringBoot AOP自动装载


在invokeBeanFactoryPostProcessors方法中完成

1、入口:parse方法委派给process方法。

2、process方法委派给processGroupImports方法。

3、grouping.getImports()方法读取META-INF/spring.factories文件下的EnableAutoConfiguration中的AopAutoConfiguration。

4、调用processImports方法,该方法为执行@Import注解的方法。

5、AopAutoConfiguration第三方spring-boot-starter-aop集成注入的bean。

@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 {
 
        }
 
    }
 
    @Configuration(proxyBeanMethods = false)
    @ConditionalOnMissingClass("org.aspectj.weaver.Advice")
    @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
            matchIfMissing = true)
    static class ClassProxyingConfiguration {
 
        @Bean
        static BeanFactoryPostProcessor forceAutoProxyCreatorToUseClassProxying() {
            return (beanFactory) -> {
                if (beanFactory instanceof BeanDefinitionRegistry) {
                    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
                    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
            };
        }
 
    }
}

说明:@Import注解使用processImports方法注入AspectJAutoProxyRegistrar这个bean。

注入AnnotationAwareAspectJAutoProxyCreator到spring容器


AspectJAutoProxyRegistrar类通过EnableAspectJAutoProxy注入(@Import)进Spring容器。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
 
    // 自动创建AspectJ代理对象这个bean
    @Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 注册一个AnnotationAwareAspectJAutoProxyCreator到Spring容器中
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
 
        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            // 判断使用cglib代理
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            // 判断暴露当前的代理对象
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

registerAspectJAnnotationAutoProxyCreatorIfNecessary方法

注册一个AnnotationAwareAspectJAutoProxyCreator到spring容器(spring容器 => beanFactory => beanDefinitionMap)

@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");
    // 判断是否已经存在AnnotationAwareAspectJAutoProxyCreator这个bean
    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 {
        // 不存在该BeanDefinition
        RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
        beanDefinition.setSource(source);
        beanDefinition.getPropertyValues().add("order", -2147483648);
        beanDefinition.setRole(2);
        // 放到beanDefinitionMap中
        registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
        return beanDefinition;
    }
}

委派给registerBeanDefinition将AnnotationAwareAspectJAutoProxyCreator放到beanDefinitionMap中

  • 本质上AnnotationAwareAspectJAutoProxyCreator还是BeanPostProcessor

Spring IOC过程中initializeBean方法,对后置处理器bean对符合要求的bean进行动态代理


  • 对bean的动态代理,在springboot的bean后置处理器中执行,也就是spring ioc的过程中来实现的。
  • SpringBoot中的bean后置处理器位置:initializeBean方法(最终来源于getBean方法)中的applyBeanPostProcessorsAfterInitialization方法
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {
    
    Object result = existingBean;
    // 遍历在BeanFactory中的BeanPostProcessor的集合
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
        // 执行后处理器
        result = beanProcessor.postProcessAfterInitialization(result, beanName);
        if (result == null) {
            return result;
        }
    }
    return result;
}

AbstractAutoProxyCreator类之postProcessAfterInitialization方法

找到适合代理的bean,然后使用配置的拦截器创建一个代理。

// 对bean执行初始化后处理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean != null) {
        // 使用类全名和name构造一个key,格式:beanClass.getName() + "_" + beanName
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            // 如果它适合被代理,那么需要封装指定bean
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

wrapIfNecessary方法

前面就是校验bean是否已经被处理过,或者干脆不需要增强。而真正开始创建代理是在getAdvicesAndAdvisorsForBean方法,至于给哪个bean生成代理等操作也都是从该方法开始的。

// 如果bean符合被代理的需要,那么将bean包装起来
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (beanName != null && 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;
    }
 
    // 如果存在增强方法则创建代理
    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方法和createProxy方法。
getAdvicesAndAdvisorsForBean方法,主要作用查找匹配bean的Advisors集合。
createProxy方法,主要作用对Advisor集合非空的bean创建代理类

核心方法1,getAdvicesAndAdvisorsForBean方法,查找匹配bean的Advisors集合


1、getAdvicesAndAdvisorsForBean方法

// 查找匹配bean的Advisor集合
@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();
}

2、委派给AbstractAdvisorAutoProxyCreator类之findEligibleAdvisors方法

// 寻找与beanClass合适的Advisor
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 调用父类方法加载配置文件中的AOP声明
    // 提取增强器Advisor(普通增强器、同步实例化增强器等)
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 寻找匹配的增强器
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 添加默认DefaultPointcutAdvisor
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

3、AnnotationAwareAspectJAutoProxyCreator类之findCandidateAdvisors方法,提取增强器Advisor

  • 获取所有bean名称
  • 挑选出被@Aspect注释的bean名称
  • 基于bean名称构建元数据工厂(MetadataAwareAspectInstanceFactory),该工厂可以创建@Aspect注释的bean
  • 最后使用全局变量advisorFactory,将MetadataAwareAspectInstanceFactory构建成一组Advisor对象
@Override
protected List<Advisor> findCandidateAdvisors() {
    // 原始构建Advisor的方式,找到超类的Advisors增强器
    List<Advisor> advisors = super.findCandidateAdvisors();
    // 重点地方,提取增强器Advisor,然后添加到Advisor的List中
    advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    return advisors;
}

基于@Aspect注解构建Advisor对象,然后放到了advisors容器中

  • AopUtils类之findAdvisorsThatCanApply方法,寻找匹配的增强器
// 寻找匹配的增强器
protected List<Advisor> findAdvisorsThatCanApply(
        List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 过滤已经得到的advisors
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}
 
 
// 寻找所有增强器中适用于当前class的增强器
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
    // 处理引介增强
    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;
}

核心方法2,AbstractAutoProxyCreator类之createProxy方法,使用指定的Bean创建aop代理


  • 1、获取当前类中的属性。
  • 2、添加代理接口。
  • 3、封装Advisor并加入到ProxyFactory中。
  • 4、设置要代理的类。
  • 5、Spring提供定制函数customizeProxyFactory,子类可以在该函数中进一步封装。
  • 6、进行获取代理操作。
// 使用指定的Bean创建aop代理
protected Object createProxy(
        Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
    
    ProxyFactory proxyFactory = new ProxyFactory();
    // 获取当前类中的相关属性
    proxyFactory.copyFrom(this);
 
    // 检查proxyTargetClass属性的设置,如果为false,那么采用jdk基于接口的jdk代理,
    // 如果为true,那么采用cglib代理
    if (!shouldProxyTargetClass(beanClass, beanName)) {
        // Must allow for introductions; can't just set interfaces to
        // the target's interfaces only.
        Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader);
        for (Class<?> targetInterface : targetInterfaces) {
            // 添加代理接口
            proxyFactory.addInterface(targetInterface);
        }
    }
 
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    for (Advisor advisor : advisors) {
        // 将Advisor封装加入到ProxyFactory中
        proxyFactory.addAdvisor(advisor);
    }
    
    // 设置要代理的类
    proxyFactory.setTargetSource(targetSource);
    // 定制代理,子类可以进一步封装
    customizeProxyFactory(proxyFactory);
    // 用来控制代理工厂被配置之后,是否还允许修改通知
    // 缺省值为false(即在代理被配置之后,不允许修改代理的配置)
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }
    // 获取代理
    return proxyFactory.getProxy(this.proxyClassLoader);
}

DefaultAopProxyFactory类之createAopProxy方法,创建AopProxy代理对象

  • 1、如果proxyTargetClass设置为false或者存在代理接口,那么直接创建Jdk代理对象,返回。
  • 2、否则如果目标类是接口,那么就创建Jdk代理对象,返回。
  • 3、如果上面都不满足,那么直接创建cglib代理对象,返回
// 创建代理简单工厂,依据配置创建代理对象
public Object getProxy(ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
}
 
// 根据AdvisedSupport(Aop配置管理器),来获取对应的代理对象
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // proxyTargetClass:目标类本身被代理而不是目标类的接口
    // hasNoUserSuppliedProxyInterfaces:是否存在代理的接口
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        // 如果目标类为null,抛出异常
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class: " +
                    "Either an interface or a target is required for proxy creation.");
        }
        // 如果目标类是接口,就创建Jdk代理对象
        if (targetClass.isInterface()) {
            return new JdkDynamicAopProxy(config);
        }
        // 默认创建cglib代理对象,进入这句话
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        // 创建Jdk代理对象
        return new JdkDynamicAopProxy(config);
    }
}

创建CglibAopProxy对象

public ObjenesisCglibAopProxy(AdvisedSupport config) {
    super(config);
}
 
public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
    Assert.notNull(config, "AdvisedSupport must not be null");
    if (config.getAdvisorCount() == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
        throw new AopConfigException("No advisors and no TargetSource specified");
    }
    this.advised = config;
    this.advisedDispatcher = new AdvisedDispatcher(this.advised);
}

CglibAopProxy.getProxy方法,获取cglib创建的代理对象

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
    if (logger.isTraceEnabled()) {
        logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
    }
 
    try {
        Class<?> rootClass = this.advised.getTargetClass();
        Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
 
        Class<?> proxySuperClass = rootClass;
        if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
            proxySuperClass = rootClass.getSuperclass();
            Class<?>[] additionalInterfaces = rootClass.getInterfaces();
            for (Class<?> additionalInterface : additionalInterfaces) {
                this.advised.addInterface(additionalInterface);
            }
        }
 
        // Validate the class, writing log messages as necessary.
        validateClassIfNecessary(proxySuperClass, classLoader);
 
        // Configure CGLIB Enhancer...
        Enhancer enhancer = createEnhancer();
        if (classLoader != null) {
            enhancer.setClassLoader(classLoader);
            if (classLoader instanceof SmartClassLoader &&
                    ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                enhancer.setUseCache(false);
            }
        }
        enhancer.setSuperclass(proxySuperClass);
        enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
 
        Callback[] callbacks = getCallbacks(rootClass);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        // fixedInterceptorMap only populated at this point, after getCallbacks call above
        enhancer.setCallbackFilter(new ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
        enhancer.setCallbackTypes(types);
 
        // Generate the proxy class and create a proxy instance.
        return createProxyClassAndInstance(enhancer, callbacks);
    }
    catch (CodeGenerationException | IllegalArgumentException ex) {
        throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
                ": Common causes of this problem include using a final class or a non-visible class",
                ex);
    }
    catch (Throwable ex) {
        // TargetSource.getTarget() failed
        throw new AopConfigException("Unexpected AOP exception", ex);
    }
}

CglibAopProxy 的内部类CglibAopProxy.DynamicAdvisedInterceptor#intercept方法


代码调用阶段


DynamicAdvisedInterceptor.intercept方法,cglib拦截方法

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;
        TargetSource targetSource = this.advised.getTargetSource();
        try {
            // 判断是否暴露代理类
            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }
            
            // 获取需要被代理的目标类
            target = targetSource.getTarget();
            // 获取被代理类的Class文件
            Class<?> targetClass = (target != null ? target.getClass() : null);
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            // 不存在增强器Advice,那么直接执行原目标类的方法
            if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                try {
                    retVal = methodProxy.invoke(target, argsToUse);
                }
                catch (CodeGenerationException ex) {
                    CglibMethodInvocation.logFastClassGenerationFailure(method);
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
                }
            }
            else {
                // 创建方法代理,执行invoke方法
                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);
            }
        }
    }
}

委派给ReflectiveMethodInvocation.proceed()方法执行,执行内容还是invoke方法调用

@Override
@Nullable
public Object proceed() throws Throwable {
    // We start with an index of -1 and increment early.
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }
 
    // 记录下当前拦截器的数量,获取拦截增强Advice
    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 {
        // 执行拦截方法
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容