AOP动态代理源码解析-EnableAspectJAutoProxy

目录

概述

AOP

JDK动态代理

Cglib动态代理

相关术语

SpringBoot配置动态代理

@EnableAspectJAutoProxy-初始化

AspectJAutoProxyRegistrar类

AopConfigUtils类

AnnotationAwareAspectJAutoProxyCreator结构

整体原理

注册流程(Spring加载bean流程)

Spring创建AOP代理解析

Spring利用ProxyFactory代理工厂来创建代理对象

代理调用逻辑实现解析

MethodBeforeAdviceInterceptor拦截器

AfterReturningAdviceInterceptor拦截器

ReflectiveMethodInvocation核心逻辑实现类

总结


概述

SpringBoot版本-2.3.6RELEASE

AOP

即面向切面编程。oop为面向对象编程。

aop采取横向抽取机制,将分期在各个方法中的重复代码提取出来,在程序编译或运行时,再将提取的方法应用到需要执行的地方。aop是oop的延伸和补充

Spring中的是基于动态代理实现。即JDK动态代理和Cglib动态代理

JDK动态代理

使用原生JDK反射和动态代理生成AOP代理,需要代理类与目标实现相同的接口。

Cglib动态代理

使用Cglib动态生成AOP代理类,需要代理类为目标类的子类。

最终由基于Cglib子类继承方式的动态代理CglibAopProxy生成代理对象,见下。

相关术语

  • Aspect 一个切面,可以理解为一个切面模块,将相关的增强内容写进同一个切面
  • Point 由AOP增强织入的程序执行节点
  • Advice 所需增强处理
    • Before 方法执行之前增强
    • After 方法执行之后增强
    • Around 环绕方法执行的整个周期
  • Pointcut 切入点,定义了将被Advice增强的一个或多个Join Point,可以使用正则表达式或模式匹配。
  • Target object 被增加的目标对象

SpringBoot动态代理

@EnableAspectJAutoProxy-初始化

在Application中配置@EnableAspectJAutoProxy

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})//引入
public @interface EnableAspectJAutoProxy {
        //为true:使用Cglib基于类创建代理;默认为false:使用java接口创建代理
    boolean proxyTargetClass() default false;

        //是否通过aop框架暴露代理,使用aopContext能访问
    boolean exposeProxy() default false;
}

AspectJAutoProxyRegistrar类

  • 注册AnnotationAwareAspectJAutoProxyCreator
  • 获取@EnableAspectJAutoProxy注解的属性信息
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //自定义注册bean:BeanDefinitionRegistry,进入到AopConfigUtils类中
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        //获取@EnableAspectJAutoProxy注解的属性信息
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }

    }
}

AopConfigUtils类

工具提供类

public abstract class AopConfigUtils {
...
        @Nullable
    public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
        return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);
    }

    @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");
        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 {
            //cls 为AnnotationAwareAspectJAutoProxyCreator
            RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
            beanDefinition.setSource(source);
            beanDefinition.getPropertyValues().add("order", -2147483648);
            beanDefinition.setRole(2);
            //将beanDefinition注册进registry中,注册名为 internalAutoProxyCreator
            registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
            return beanDefinition;
        }
    }
}

AnnotationAwareAspectJAutoProxyCreator结构

image.png

由上图:AnnotationAwareAspectJAutoProxyCreator可看作为后置处理器,因实现InstantiationAwareBeanPostProcessor

并用BeanFactoryAware为自动装配的BeanFactory

整体原理

在bean实例化之前调用的是postProcessBeforeInstantiation方法,主要进行了一些必要判断,以及如果通知方法list集合为空,进行遍历所有@Aspect等先关声明切面注解的类,并解析该类中的各个切面和切面类型为一个个的通知方法保存到list中(这个list位于这个后置处理器的aspectJAdvisorsBuilder属性下的advisorsCache属性中),在bean实例化后调用后置处理器的postProcessAfterInitialization用于将对象生成动态代理对象返回放入容器中。

 

注册流程(Spring加载bean流程)

public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                //调用beanFactory(这里的beanFactory实例是:DefaultListableBeanFactory)的后置处理器
                this.invokeBeanFactoryPostProcessors(beanFactory);
                //注册后置处理器,用于拦截bean的创建
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            ...
        }
    }
  1. Application启动,创建IOC容器 传入配置类:new AnnotationConfigApplicationContext(ConfigOfAOP.class)
  2. 调用refresh()方法,刷新容器,见上
  3. refresh()方法调用了一个方法 registerBeanPostProcessors(beanFactory),注册后置处理器,用于拦截bean的创建。也是在这个方法中完成了AnnotationAwareAspectJAutoProxyCreator的注册。该方法的主要逻辑在PostProcessorRegistrationDelegate类中的registerBeanPostProcessors方法中。
  4. registerBeanPostProcessors方法中注册了所有的BeanPostProcessor,所以AnnotationAwareAspectJAutoProxyCreator也在这里注册完成。而从AnnotationAwareAspectJAutoProxyCreator类的层次接口可以看出,该类实现了Ordered接口。所以它是在注册实现Ordered接口的BeanPostProcessor是完成注册
  5. 初始化bean时,initializeBean方法会调用BeanPostProcessor和BeanFactory以及Aware接口的相关方法,来初始化bean。initializeBean方法执行成功,AnnotationAwareAspectJAutoProxyCreator注册和初始化成功。
  6. 这时再回到第3步中,BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class)执行成功,目标bean成功注册后,将注册完成的beanPostProcessor,排序后注册到BeanFactory中。

其中:AnnotationAwareAspectJAutoProxyCreator调用时机发生在第2步。

postProcessBeforeInstantiation方法是InstantiationAwareBeanPostProcessor接口中定义的方法,

applyBeanPostProcessorsAfterInitialization方法会调用BeanPostProcessor接口中postProcessAfterInitialization方法。而且InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试用后置处理器返回对象的;BeanPostProcessor是在Bean对象创建完成初始化前后调用的。从AnnotationAwareAspectJAutoProxyCreator类的层次结构可以看出,该类实现了InstantiationAwareBeanPostProcessor接口,它会在所有bean实例创建前进行拦截,这也是AOP代理的关键所在。

Spring创建AOP代理解析

上续为bean(AnnotationAwareAspectJAutoProxyCreator)的加载。现在解析其内部实现AOP代理逻辑。

AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor。

每次创建bean实例前都会调用AnnotationAwareAspectJAutoProxyCreator类的postProcessBeforeInstantiation()方法。

1.AnnotationAwareAspectJAutoProxyCreator继承AbstractAutoProxyCreator,AbstractAutoProxyCreator实现了postProcessBeforeInstantiation方法,如下:

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = this.getCacheKey(beanClass, beanName);
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //判断当前bean是否在advisedBeans中(advisedBeans保存了所有需要增强的bean)
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
                        //判断当前bean是否基础类型Advice、Pointcut、Advisor、AopInfrastructureBean,或是否为切面(@Aspect)
            //是否需要跳过
            if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        //加载自定义切面
        TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
         
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        } else {
            return null;
        }
    }
}

其中逻辑为:

  1. 判断当前bean是否在advisedBeans(增强bean的集合)中,增强bean是指切入点表达式包含的类。
  2. 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect)
  3. 是否需要跳过,获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】,如果增强器是 AspectJPointcutAdvisor 类型的,则返回true(封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor类型)

2.bean创建完成后会调用applyBeanPostProcessorsAfterInitialization方法,继而调用后置处理器的postProcessAfterInitialization方法。用于创建代理对象

postProcessAfterInitialization也处理AbstractAutoProxyCreator实现

        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                //包装bean,这里会获取bean的增强器,并且生成动态代理
                return this.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;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            //不是增强类,则返回
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
            //获取当前bean的增强器
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                //放入advisedBeans
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                //创建增强bean的代理对象
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
    ...
    //接上 创建增强bean的代理对象
    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 (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
         
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        //将增强器保存入代理factory中
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
                //返回创建代理对象
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

Spring利用ProxyFactory代理工厂来创建代理对象

ProxyFactory

public class ProxyFactory extends ProxyCreatorSupport {
...
        public Object getProxy(@Nullable ClassLoader classLoader) {
        return this.createAopProxy().getProxy(classLoader);
    }
}

接上ProxyCreatorSupport.createAopProxy

        protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }

        return this.getAopProxyFactory().createAopProxy(this);
    }

接上DefaultAopProxyFactory.createAopProxy

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            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.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) 
                ? new ObjenesisCglibAopProxy(config)   //基于类创建Cglib动态代理
                : new JdkDynamicAopProxy(config));   //基于接口创建JDK动态代理
            }
        }
    }

接上,JdkDynamicAopProxy类解析

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    private static final long serialVersionUID = 5531744639992436476L;
    private static final Log logger = LogFactory.getLog(JdkDynamicAopProxy.class);
    private final AdvisedSupport advised;
    private boolean equalsDefined;
    private boolean hashCodeDefined;

    public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");
        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
            throw new AopConfigException("No advisors and no TargetSource specified");
        } else {
            this.advised = config;
        }
    }

    public Object getProxy() {
        return this.getProxy(ClassUtils.getDefaultClassLoader());
    }

    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }

        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        //返回代理实例对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }
    ...
    //对当前proxy调用其上的任何方法,都将转到这个方法
    @Nullable
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        TargetSource targetSource = this.advised.targetSource;
        Object target = null;

        Boolean var8;
        try {
            if (this.equalsDefined || !AopUtils.isEqualsMethod(method)) {
                if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                    Integer var18 = this.hashCode();
                    return var18;
                }

                if (method.getDeclaringClass() == DecoratingProxy.class) {
                    Class var17 = AopProxyUtils.ultimateTargetClass(this.advised);
                    return var17;
                }

                Object retVal;
                if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                    retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
                    return retVal;
                }

                if (this.advised.exposeProxy) {
                    oldProxy = AopContext.setCurrentProxy(proxy);
                    setProxyContext = true;
                }

                target = targetSource.getTarget();
                Class<?> targetClass = target != null ? target.getClass() : null;
                //获取当前调用方法的拦截链
                List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                //如果没有拦截链,则直接调用Joinpoint连接点的方法
                if (chain.isEmpty()) {
                    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
                } else {
                    根据给定的拦截链和方法调用信息,创建新的MethodInvocation对象,整个拦截链的工作逻辑都在这个ReflectiveMethodInvocation里
                    MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                    retVal = invocation.proceed();
                }

                Class<?> returnType = method.getReturnType();
                if (retVal != null && retVal == target && returnType != Object.class && returnType.isInstance(proxy) && !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                    retVal = proxy;
                } else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                    throw new AopInvocationException("Null return value from advice does not match primitive return type for: " + method);
                }

                Object var12 = retVal;
                return var12;
            }

            var8 = this.equals(args[0]);
        } finally {
            if (target != null && !targetSource.isStatic()) {
                targetSource.releaseTarget(target);
            }

            if (setProxyContext) {
                AopContext.setCurrentProxy(oldProxy);
            }

        }

        return var8;
    }
}

接上,CglibAopProxy类解析

    private static final int AOP_PROXY = 0;
    private static final int INVOKE_TARGET = 1;
    private static final int NO_OVERRIDE = 2;
    private static final int DISPATCH_TARGET = 3;
    private static final int DISPATCH_ADVISED = 4;
    private static final int INVOKE_EQUALS = 5;
    private static final int INVOKE_HASHCODE = 6;
    protected static final Log logger = LogFactory.getLog(CglibAopProxy.class);
    private static final Map<Class<?>, Boolean> validatedClasses = new WeakHashMap();
    protected final AdvisedSupport advised;
    @Nullable
    protected Object[] constructorArgs;
    @Nullable
    protected Class<?>[] constructorArgTypes;
    private final transient CglibAopProxy.AdvisedDispatcher advisedDispatcher;
    private transient Map<Method, Integer> fixedInterceptorMap = Collections.emptyMap();
    private transient int fixedInterceptorOffset;
    
    public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");
        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
            throw new AopConfigException("No advisors and no TargetSource specified");
        } else {
            this.advised = config;
            this.advisedDispatcher = new CglibAopProxy.AdvisedDispatcher(this.advised);
        }
    }
    ...
    public Object getProxy() {
        return this.getProxy((ClassLoader)null);
    }

    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;
            int x;
            if (rootClass.getName().contains("$$")) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class<?> additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }

                        //检查
            this.validateClassIfNecessary(proxySuperClass, classLoader);
            Enhancer enhancer = this.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 = this.getCallbacks(rootClass);
            Class<?>[] types = new Class[callbacks.length];

            for(x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
            //返回实例
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (IllegalArgumentException | CodeGenerationException var9) {
            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", var9);
        } catch (Throwable var10) {
            throw new AopConfigException("Unexpected AOP exception", var10);
        }
    }

}

代理调用逻辑实现解析

JdkDynamicAopProxy 和CglibAopProxy只是创建代理方式的两种方式而已,实际上我们为方法调用添加的各种Advice的执行逻辑都是统一的。

1.在Spring的底层,会把我们定义的各个Adivce分别包裹成一个MethodInterceptor,这些Advice按照加入Advised顺序,构成一个AdivseChain。

image.png

可以看出MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor都实现MethodInterceptor。那AroundAdive因其本身就是一个MethodInterceptor,就不需要转换逻辑了。

MethodBeforeAdviceInterceptor拦截器

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
    private final MethodBeforeAdvice advice;

    public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        //在调用方法之前,先执行BeforeAdvice
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
        //调用invocation  其实现为ReflectiveMethodInvocation 
        return mi.proceed();
    }
}

AfterReturningAdviceInterceptor拦截器

public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
    private final AfterReturningAdvice advice;

    public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
        Assert.notNull(advice, "Advice must not be null");
        this.advice = advice;
    }

    public Object invoke(MethodInvocation mi) throws Throwable {
        //调用invocation 其实现为ReflectiveMethodInvocation 
        Object retVal = mi.proceed();
        //调用成功后,调用AfterReturningAdvice
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}

2.当发生调用代理对象方法时,Spring会把这个方法调用转换成一个MethodInvocation对象,然后结合上述的我们添加的各种Advice,组成一个ReflectiveMethodInvocation。

ReflectiveMethodInvocation核心逻辑实现类

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {

...

    @Nullable
    public Object proceed() throws Throwable {
        //如果没有拦截器,则直接调用Joinpoint上的method,即直接调用MethodInvocation
        if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
            return this.invokeJoinpoint();
        } else {
            // 取得第拦截器链上第N个拦截器 
            Object interceptorOrInterceptionAdvice = 
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            //当前拦截器是符合拦截规则,每个拦截器可以定义是否特定的类和方法名是否符合拦截规则
                        //实际上PointCut定义的方法签名最后会转换成这个MethodMatcher,并置于拦截器中
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                InterceptorAndDynamicMethodMatcher dm = 
                (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
                Class<?> targetClass = 
                this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
                //当有拦截时,调用拦截器
                //当没有拦截时,直接向前推进
                return dm.methodMatcher.matches(this.method, targetClass, this.arguments) 
                ? dm.interceptor.invoke(this) : this.proceed();
            } else {
                return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    }
}

 

总结:容器可以创建两种动态代理对象:JDK动态代理对象和CGLIB动态代理对象,并最终返回创建完成的代理对象。以后容器中获取到的bean就是这个组件的动态代理bean,执行目标方法的时候,代理对象就会执行通知方法的流程。

总结

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个InstantiationAwareBeanPostProcessor类型后置处理器
  4.  容器的创建流程:
  1. registerBeanPostProcessors():注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
  2. finishBeanFactoryInitialization():初始化剩下的单实例bean
  3. 创建业务逻辑组件和切面组件
    1. 组件创建完之后,判断组件是否需要增强。如是增强:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(Cglib)
    2. AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值