springboot启动源码分析8——aop

Springboot源码分析8——aop动态代理

springboot启动源码分析1——初步初始化

springboot启动源码分析2——run方法分析

springboot启动源码分析3——环境配置

springboot启动源码分析4——刷新容器

springboot启动源码分析5——后续处理内容

Spring Boot启动源码分析6——refresh的invokeBeanFactoryPostProcessors方法详解

springboot启动源码分析7——自动配置

springboot启动源码分析8——aop

代理类对应的调用

下面我们来讲一下springboot中的aop的动态代理是在哪里进行配置创建的。

aop的动态代理的创建getProxy主要是调用ProxyFactory中的getProxy方法进行配置相关的动态代理。

如下
在这里插入图片描述
该进行获取对应的aop代理的配置是在refresh()进行刷新方法的this.finishBeanFactoryInitialization(beanFactory);方法中进行对应的获取和配置的。

在这里插入图片描述

同样我们都知道aop的动态代理主要有cglib和JDK的动态代理,那么这里是如何进行判断的呢?

首先其在createAopProxy()的时候就会根据类型进行判断获取,进入该方法,

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

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

主要看createAopProxy()方法。点进该方法。如果没有进行debug的情况下,也可以直接alt+ctrl+点击该方法直接进入,该方法就只有一个实现类DefaultAopProxyFactory。

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    //如果本地系统中有"org.graalvm.nativeimage.imagecode"或者是没有经过优化的,并且该配置类不能是被代理类并且没有提供代理接口,那么就直接返回JDK代理
    if (NativeDetector.inNativeImage() || !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 {
            //注意这里的代理目标类不是接口,而不要当做是不是实现接口的类,并且不是代理类,并且不是Lambda类。这样就会进行cglib代理,否则就会返回JDK的动态代理。
            return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) && !ClassUtils.isLambdaClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
        }
    }
}

接下来我们在来看看cglib和JDK代理有什么不同

首先我们来看看cglib的动态代理

Cglib的动态代理

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));
		//通过getCallbacks进行设置相对应的拦截器
        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);
    }
}

该动态代理是调用CglibAopProxy类中的getProxy()方法。

前面主要进行一些配置,就是获取目标类,然后在进行相对应的根据他来添加和设置一些属性。

我们主要看到最后一步,this.createProxyClassAndInstance(enhancer, callbacks)方法

protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
    Class<?> proxyClass = enhancer.createClass();
    Object proxyInstance = null;
    if (objenesis.isWorthTrying()) {
        try {
            //根据代理类进行创建实例
            //这里的objenesis是当前类SpringObjenesis。
            //主要就是进行判断是否使用缓存进行创建,如果使用缓存的话就直接使用instantiator来newInstance
            //       否者就new一个instantiator来进行newInstance
            proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
        } catch (Throwable var7) {
            logger.debug("Unable to instantiate proxy using Objenesis, falling back to regular proxy construction", var7);
        }
    }

    if (proxyInstance == null) {
        try {
            Constructor<?> ctor = this.constructorArgs != null ? proxyClass.getDeclaredConstructor(this.constructorArgTypes) : proxyClass.getDeclaredConstructor();
            ReflectionUtils.makeAccessible(ctor);
            proxyInstance = this.constructorArgs != null ? ctor.newInstance(this.constructorArgs) : ctor.newInstance();
        } catch (Throwable var6) {
            throw new AopConfigException("Unable to instantiate proxy using Objenesis, and regular proxy instantiation via default constructor fails as well", var6);
        }
    }

    ((Factory)proxyInstance).setCallbacks(callbacks);
    return proxyInstance;
}

最后我们在烂看一下相对应的设置拦截器getCallbacks()

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
    //这里是处理expose-proxy中
    boolean exposeProxy = this.advised.isExposeProxy();
    boolean isFrozen = this.advised.isFrozen();
    boolean isStatic = this.advised.getTargetSource().isStatic();
    //将对应的拦截器封装到DynamicAdvisedInterceptor中
    Callback aopInterceptor = new CglibAopProxy.DynamicAdvisedInterceptor(this.advised);
    Object targetInterceptor;
    if (exposeProxy) {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
    } else {
        targetInterceptor = isStatic ? new CglibAopProxy.StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.DynamicUnadvisedInterceptor(this.advised.getTargetSource());
    }

    Callback targetDispatcher = isStatic ? new CglibAopProxy.StaticDispatcher(this.advised.getTargetSource().getTarget()) : new CglibAopProxy.SerializableNoOp();
    
    Callback[] mainCallbacks = new Callback[]{
        aopInterceptor //将拦截器加入到callback中
        , (Callback)targetInterceptor
        , new CglibAopProxy.SerializableNoOp()
        , (Callback)targetDispatcher
        , this.advisedDispatcher
        , new CglibAopProxy.EqualsInterceptor(this.advised)
        , new CglibAopProxy.HashCodeInterceptor(this.advised)};
    Callback[] callbacks;
    if (isStatic && isFrozen) {
        Method[] methods = rootClass.getMethods();
        Callback[] fixedCallbacks = new Callback[methods.length];
        this.fixedInterceptorMap = CollectionUtils.newHashMap(methods.length);

        for(int x = 0; x < methods.length; ++x) {
            Method method = methods[x];
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
            fixedCallbacks[x] = new CglibAopProxy.FixedChainStaticTargetInterceptor(chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
            this.fixedInterceptorMap.put(method, x);
        }

        callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
        System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
        System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
        this.fixedInterceptorOffset = mainCallbacks.length;
    } else {
        callbacks = mainCallbacks;
    }

    return callbacks;
}

JDK的动态代理

下面我们再来看看对应的JDK的aop的动态代理

这里主要执行的就是JDKDynamicAopProxy继承了InvocationHandler,所以aop对应的代理会调用他的invoke方法。

如下

@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 {
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            Boolean var18 = this.equals(args[0]);
            return var18;
        }

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

        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);
        if (chain.isEmpty()) {
            //这里是判断是否有拦截器,如果没有什么拦截器,那么就直接调用切点的方法。
            Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
            retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
        } else {
            //对上面创建的拦截器使用ReflectiveMethodInvocation进行了链的封装。,并且在下面的proceed方法中会进行对实现的拦截器进行逐一调用
            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;
}

我们来看一下对应的proceed()方法

@Nullable
public Object proceed() throws Throwable {
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        //这里执行完成所有的增强方法之后,在执行切点的方法。
        return this.invokeJoinpoint();
    } else {
        //获取相对应的拦截器
        Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
        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 {
            //这里是普通的拦截器,上面的是动态进行匹配的拦截器,
            //如果是普通的拦截器那么就直接调用拦截器的方法。比如MethodBeforeAdviceInterceptor、AspcetJAroundAdvice等
            //这里的入参为this,就是保证当前实例中调用链的执行。
            return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值