3.SpringAop之ProxyCreatorSupport

1.类继承关系

2.解析

ProxyCreatorSupport继承AdvisedSupport,主要提供了createAopProxy方法用来得到用来生成代理对象的AopProxy对象

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

AopProxy有两种实现,JdkDynamicAopProxy和ObjenesisCglibAopProxy

public interface AopProxy {

    Object getProxy();

    Object getProxy(ClassLoader classLoader);

}

具体选择哪一种代理生成方式使用了DefaultAopProxyFactory这个工厂类来决定
在DefaultAopProxyFactory的createAopProxy方法中,会根据Aop的配置以及代理类的信息来选择使用jdk还是cglib来生成动态代理

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        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.");
        }
        if (targetClass.isInterface()) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

讲一下我们比较熟悉的JDK动态代理吧

JdkDynamicAopProxy 实现了 InvocationHandler,也就是说生成代理的时候,它要把自己当做参数传进去

public Object getProxy(ClassLoader classLoader) {
    if (logger.isDebugEnabled()) {
        logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
    }
    Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
    findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
    return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

显而易见,具体的代理执行拦截器链的逻辑也就在JdkDynamicAopProxy 的invoke方法中
截取invoke中比较核心的代码片段

// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
    // 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.
    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
}
else {
    // We need to create a method invocation...
    invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    // Proceed to the joinpoint through the interceptor chain.
    retVal = invocation.proceed();
}

先通过AdvisedSupport的getInterceptorsAndDynamicInterceptionAdvice拿到拦截器链,然后封装到ReflectiveMethodInvocation进行链式调用

下面来看下如何在ReflectiveMethodInvocation中执行链式调用,逻辑在它的proceed方法中

public Object proceed() throws Throwable {
    //拦截器下标从-1开始
    //如果没有拦截器链,直接进行连接点,也就是被切方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        //直接执行连接点逻辑
                return invokeJoinpoint();
    }
    //获取下一个拦截器,第一次进来就-1+1=0,也就是第一个
    Object interceptorOrInterceptionAdvice =
            this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    //判断interceptorOrInterceptionAdvice是否是动态拦截器
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        InterceptorAndDynamicMethodMatcher dm =
                (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
            //动态拦截器的methodMatcher匹配
                        //invoke执行完切面逻辑后,会调用this执行proceed方法,再次回到这个方法
            return dm.interceptor.invoke(this);
        }
        else {
            //动态拦截器的methodMatcher不匹配,再次执行proceed,相当于调用下一个拦截器
            return proceed();
        }
    }
    else {
        //如果是静态拦截器,直接执行
                //invoke执行完切面逻辑后,会调用this执行proceed方法,再次回到这个方法
        return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
}

invokeJoinpoint用反射来执行连接点的逻辑,也就是执行被切方法

protected Object invokeJoinpoint() throws Throwable {
        return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
    }
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
            throws Throwable {

        // Use reflection to invoke the method.
        try {
            ReflectionUtils.makeAccessible(method);
            return method.invoke(target, args);
        }
        catch (InvocationTargetException ex) {
            // Invoked method threw a checked exception.
            // We must rethrow it. The client won't see the interceptor.
            throw ex.getTargetException();
        }
        catch (IllegalArgumentException ex) {
            throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" +
                    method + "] on target [" + target + "]", ex);
        }
        catch (IllegalAccessException ex) {
            throw new AopInvocationException("Could not access method [" + method + "]", ex);
        }
    }

Cglib的实现也大同小异,代理的生成方式不同,但是拦截器链的调用逻辑应该一致

总结

ProxyCreatorSupport专注于提供生成代理对象的AopProxy,具体使用AopProxy生成代理对象在ProxyFactoryBean和ProxyFactory中使用,将在下一章讲解

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容