Spring-Aop 底层源码解析--Spring 如何通过代理进行Aop


前言

Spring 中所谓的Aop 就是为已经存在的bean ,动态的插入一段代理逻辑,从而实现某些指定的方法进行增强。


一、spirng 的aop是什么:

在Spring框架中,Spring AOP 是核心容器的一部分,允许通过代理模式为对象提供横切关系。代理模式允许Spring通过一个代理类来包装用户定义的bean,以便在调用实际bean之前或之后插入附加的行为。

二、spring 中如何使用aop:

2.1 使用 ProxyFactory 生成代理对象

准备代码:

import org.springframework.stereotype.Component;

@Component
public class AspectTestService {

    public void test(){
        System.out.println("test  方法调用");
    }

    public void abc(){
        System.out.println("abc  方法调用");
    }
}

使用 ProxyFactory 进行对象的代理:

package com.example.springdabaihua.aspect.proxy;

import com.example.springdabaihua.aspect.service.AspectTestService;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.*;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

import java.lang.reflect.Method;

public class ProxyTestMain {

    public static void main(String[] args) {
        AspectTestService service = new AspectTestService();
//        service.test();
        ProxyFactory factory = new ProxyFactory();
        factory.setTarget(service);
        // 统一设置代理逻辑
        factory.addAdvice(new MethodBeforeAdvice() {
            // 方法的前置
            @Override
            public void before(Method method, Object[] args, Object target) throws Throwable {
                System.out.println("method before");
            }
        });
        factory.addAdvice(new AfterReturningAdvice() {
            //  方法调用之后放回之前
            @Override
            public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
                System.out.println("method after");
            }
        });
        factory.addAdvice(new MethodInterceptor() {
            // 方法的环绕
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("method before Interceptor1");

                Object proceed = invocation.proceed();

                System.out.println("method after Interceptor1");
                return proceed;
            }
        });
        factory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("method before Interceptor2");

                Object proceed = invocation.proceed();

                System.out.println("method after Interceptor2");
                return proceed;
            }
        });


        factory.addAdvice(new ThrowsAdvice() {
//            @Override
            public void afterThrowing( Method method, Object[] args, Object target,RuntimeException ex)  {
                System.out.println("method error");
            }

        });

        //  对匹配的方法 设置代理逻辑
        factory.addAdvisor(new PointcutAdvisor() {
            @Override
            public Pointcut getPointcut() {
                return new StaticMethodMatcherPointcut() {
                    @Override
                    public boolean matches(Method method, Class<?> targetClass) {
                        //  匹配的方法
                        return method.getName().equals("abc");
                    }
                };
            }

            @Override
            public Advice getAdvice() {
                return new MethodBeforeAdvice() {
                    // 代理逻辑
                    @Override
                    public void before(Method method, Object[] args, Object target) throws Throwable {
                        System.out.println("method before");
                    }
                };
            }

            @Override
            public boolean isPerInstance() {
                return false;
            }
        });
        AspectTestService proxy = (AspectTestService) factory.getProxy();
        proxy.test();
        proxy.abc();
    }
}

通过ProxyFactory,我们可以不再关系到底是用cglib还是jdk动态代理了,ProxyFactory会帮我们去判断,如果AspectTestService实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。

2.2 BeanNameAutoProxyCreator 为已经存在的bean 代理:

  @Bean
 public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
     BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
     beanNameAutoProxyCreator.setBeanNames("aspectTestService");
     beanNameAutoProxyCreator.setInterceptorNames("testBeforeAdvice","testAroundAdvice");
     beanNameAutoProxyCreator.setProxyTargetClass(true);

     return beanNameAutoProxyCreator;
 }
 @Bean
 public MethodBeforeAdvice testBeforeAdvice(){
     return  new MethodBeforeAdvice() {
         // 方法的前置
         @Override
         public void before(Method method, Object[] args, Object target) throws Throwable {
             System.out.println("method before");
         }
     };

 }
 @Bean
 public MethodInterceptor testAroundAdvice(){
     return new MethodInterceptor() {
         @Override
         public Object invoke(MethodInvocation invocation) throws Throwable {
             System.out.println("before...");
             Object result = invocation.proceed();
             System.out.println("after...");
             return result;
         }
     };
 }

这里我们为已经存在的aspectTestService 增加了两个代理逻辑一个是方法之前之前的before ,一个是 around; 这里增加的Advice 的类型和 使用 ProxyFactory 进行对象的代理 是相同的;这样可以实现为已经存在的bean 进行逻辑的增强了;

2.2 DefaultPointcutAdvisor 为已经存在的bean 中方法进行代理:

首先导入 DefaultAdvisorAutoProxyCreator 让spirng 可以收集我们定义的Advisor:

@Import(DefaultAdvisorAutoProxyCreator.class)

然后设置我们自己的Advisor:

 @Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
    NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
    // 对已经存在的bean 中的abc 方法进行代理
    pointcut.addMethodName("abc");

    DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
    defaultPointcutAdvisor.setPointcut(pointcut);
    defaultPointcutAdvisor.setAdvice(new MethodBeforeAdvice() {
        @Override
        public void before(Method method, Object[] args, Object target) throws Throwable {
            System.out.println("method berfore 执行");
        }
    });
    return defaultPointcutAdvisor;
}

三、Spring ProxyFactory 的工作原理:

3.1 ProxyFactory getProxy() 获取代理类:

public Object getProxy() {
	// 先创建一个代理 然后获取代理对象
    return this.createAopProxy().getProxy();
}
// synchronized 对象锁
protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        this.activate();
    }
    // getAopProxyFactory 确定 使用jdk 还是cglib 代理
    return this.getAopProxyFactory().createAopProxy(this);
}

DefaultAopProxyFactory 下 createAopProxy 获取动态代理:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
//  config.isOptimize() 默认false 是否使用优化,因为早期的cglib 效率要高于jdk
//  config.isProxyTargetClass() 默认false  代理的是否是一个类 ,false 代表要代理的是一个接口
//  true 表示代理类 则使用cglib
//  hasNoUserSuppliedProxyInterfaces  是否有添加接口,添加了接口为false ,没有添加接口 true
        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 {
//  被代理的类是一个接口 或者 产生的代理类,是jdk 的动态代理类,则使用jdk 动态代理
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) && !ClassUtils.isLambdaClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}

3.2 jdk 的动态代理:JdkDynamicAopProxy

获取动态代理:

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

    return Proxy.newProxyInstance(this.determineClassLoader(classLoader), this.proxiedInterfaces, this);
}

jdk 动态代理方法的执行:

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

    Object var12;
    try {
		// 如果是 equals 则不需要代理
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            Boolean var18 = this.equals(args[0]);
            return var18;
        }
		// 如果是 hashCode 则不需要代理
        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            Integer var17 = this.hashCode();
            return var17;
        }
			// 
        if (method.getDeclaringClass() == DecoratingProxy.class) {
            Class var16 = AopProxyUtils.ultimateTargetClass(this.advised);
            return var16;
        }

        Object retVal;
        if (!this.advised.opaque && method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAssignableFrom(Advised.class)) {
            retVal = AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            return retVal;
        }
		// 如果 exposeProxy 是true(默认false) 则暴露代理对象到 线程中,当前线程后续可以直接获取到代理对象
        if (this.advised.exposeProxy) {
            oldProxy = AopContext.setCurrentProxy(proxy);
            setProxyContext = true;
        }
		// 获取被代理对象
        target = targetSource.getTarget();
        Class<?> targetClass = target != null ? target.getClass() : null;
		// 获取 advise  的链路
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
        if (chain.isEmpty()) {
			// 没有代理链
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
			// 直接执行被代理对象的方法
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        } else {
			// 获取到 MethodInvocation  对象,
            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);
        }

        var12 = retVal;
    } finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }

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

    }

    return var12;
}

advise 链路的获取:getInterceptorsAndDynamicInterceptionAdvice

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		// 先从缓存拿
    MethodCacheKey cacheKey = new MethodCacheKey(method);
    List<Object> cached = (List)this.methodCache.get(cacheKey);
    if (cached == null) {
		// 缓存拿不到,则进行获取
        cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);
        this.methodCache.put(cacheKey, cached);
    }

    return cached;
}

getInterceptorsAndDynamicInterceptionAdvice:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass) {
    AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
     //  获取添加的advisor
    Advisor[] advisors = config.getAdvisors();
    List<Object> interceptorList = new ArrayList(advisors.length);
    Class<?> actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
    Boolean hasIntroductions = null;
    Advisor[] var9 = advisors;
    int var10 = advisors.length;

    for(int var11 = 0; var11 < var10; ++var11) {
        // 遍历每个advisor
        Advisor advisor = var9[var11];
        if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
             // 类匹配器是否匹配
            if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                boolean match;
                 // 方法匹配器是否匹配
                if (mm instanceof IntroductionAwareMethodMatcher) {
                    if (hasIntroductions == null) {
                        hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
                    }

                    match = ((IntroductionAwareMethodMatcher)mm).matches(method, actualClass, hasIntroductions);
                } else {
                    match = mm.matches(method, actualClass);
                }

                if (match) {
                     // 如果都匹配 在将 advisor 转为 MethodInterceptor
                    MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
                    if (mm.isRuntime()) {
                         // 如果是运行时
                        MethodInterceptor[] var17 = interceptors;
                        int var18 = interceptors.length;

                        for(int var19 = 0; var19 < var18; ++var19) {
                            MethodInterceptor interceptor = var17[var19];
                             // 对其进行InterceptorAndDynamicMethodMatcher 包装,
                             // 在对传入的参数进行匹配
                            interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                        }
                    } else {

                        interceptorList.addAll(Arrays.asList(interceptors));
                    }
                }
            }
        } else if (advisor instanceof IntroductionAdvisor) {
            IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
            if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        } else {
            Interceptor[] interceptors = registry.getInterceptors(advisor);
            interceptorList.addAll(Arrays.asList(interceptors));
        }
    }

    return interceptorList;
}

MethodInterceptor 的对象包装:registry.getInterceptors(advisor);

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
    List<MethodInterceptor> interceptors = new ArrayList(3);
		// 获取 advice
    Advice advice = advisor.getAdvice();
	// 如果本身就是 MethodInterceptor 则直接添加
    if (advice instanceof MethodInterceptor) {
        interceptors.add((MethodInterceptor)advice);
    }
		//  对 advice  进行3个适配器的匹配:
		// MethodBeforeAdviceAdapter/ AfterReturningAdviceAdapter/ThrowsAdviceAdapter
    Iterator var4 = this.adapters.iterator();
    while(var4.hasNext()) {
        AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
        if (adapter.supportsAdvice(advice)) {
			// 如果适配则调用适配器的getInterceptor 方法获取MethodInterceptor
            interceptors.add(adapter.getInterceptor(advisor));
        }
    }

    if (interceptors.isEmpty()) {
        throw new UnknownAdviceTypeException(advisor.getAdvice());
    } else {
        return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[0]);
    }
}

3个适配器:正是因为底层去匹配了这3个适配器,所以我们在代码里才可以对其进行实现
(1) 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;
    }

    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
		// 先调用目标的方法
        Object retVal = mi.proceed();
		// 在调用 advice 中的 afterReturning 方法
        this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
        return retVal;
    }
}

(2) MethodBeforeAdviceAdapter:

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

    @Nullable
    public Object invoke(MethodInvocation mi) throws Throwable {
		// 先调用 advice 的befor 方法
        this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
		// 在调用目标方法
        return mi.proceed();
    }
}

(3) ThrowsAdviceAdapter:

public ThrowsAdviceInterceptor(Object throwsAdvice) {
    Assert.notNull(throwsAdvice, "Advice must not be null");
    this.throwsAdvice = throwsAdvice;
    Method[] methods = throwsAdvice.getClass().getMethods();
    Method[] var3 = methods;
    int var4 = methods.length;
		// 遍历throwsAdvice 的所有方法
    for(int var5 = 0; var5 < var4; ++var5) {
        Method method = var3[var5];
        if (method.getName().equals("afterThrowing") && (method.getParameterCount() == 1 || method.getParameterCount() == 4)) {
				// 获取到异常类型参数
            Class<?> throwableParam = method.getParameterTypes()[method.getParameterCount() - 1];
            if (Throwable.class.isAssignableFrom(throwableParam)) {
				// 将异常和 方法 作为 key 和value 放入到map 中
                this.exceptionHandlerMap.put(throwableParam, method);
                if (logger.isDebugEnabled()) {
                    logger.debug("Found exception handler method on throws advice: " + method);
                }
            }
        }
    }

    if (this.exceptionHandlerMap.isEmpty()) {
        throw new IllegalArgumentException("At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
    }
}

@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
    try {
		// 方法调用
        return mi.proceed();
    } catch (Throwable var4) {
		 // 如果异常了,则得到改异常对应的方法
        Method handlerMethod = this.getExceptionHandler(var4);
        if (handlerMethod != null) {
			// 方法不为空,则执行方法
            this.invokeHandlerMethod(mi, var4, handlerMethod);
        }
		// 最终抛出异常
        throw var4;
    }
}

代理逻辑链路的执行:ReflectiveMethodInvocation下 proceed 方法

@Nullable
public Object proceed() throws Throwable {
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
		// 如果没有advise    链路/ 或者advise    链路的方法都执行完了, 则直接调用目标方法
        return this.invokeJoinpoint();
    } else {
		// 进行循环遍历,先取出第一个advise
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// 如果是 InterceptorAndDynamicMethodMatcher 对象
			// 如果改advise 是runTime  的会对其封装成 InterceptorAndDynamicMethodMatcher 
            InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;
            Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();
			// 进行参数匹配,如果匹配则执行改advise    的invoke 方法,否则进行下一次循环
            return dm.methodMatcher.matches(this.method, targetClass, this.arguments) ? dm.interceptor.invoke(this) : this.proceed();
        } else {
			// 调用每个 advise    的invoke 方法 ,每次调用都对currentInterceptorIndex ++
			// 从而实现对每个 advise     的invoke 的调用
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}

3.3 cglib的动态代理:CglibAopProxy

获取动态代理:

public Object getProxy() {
    return this.getProxy((ClassLoader)null);
}

getProxy 获取代理对象:

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

总结:

本文列举了通过 Spring 中的BeanNameAutoProxyCreator ,DefaultPointcutAdvisor 来为bean 进行代理逻辑的实现,并对底层使用的ProxyFactory 工作原理进行介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值