Spring源码分析Spring AOP

3.SpringAop之ProxyCreatorSupport

2018-01-23  本文已影响5人  土豆肉丝盖浇饭

1.类继承关系

image

2.解析

ProxyCreatorSupport继承AdvisedSupport,在此基础上提供了createAopProxy方法用来得到生成代理对象的AopProxy对象

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

并且提供了事件监听机制

getAopProxyFactory()默认使用DefaultAopProxyFactory
DefaultAopProxyFactory 根据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);
    }
}

AopProxy是实际生成代理的接口,实现类有JdkDynamicAopProxy和ObjenesisCglibAopProxy

public interface AopProxy {

    Object getProxy();

    Object getProxy(ClassLoader classLoader);

}

讲一下我们比较熟悉的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);
}

具体的代理执行通知器的逻辑也就在它的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();
}

这边用到了前一章讲到的getInterceptorsAndDynamicInterceptionAdvice以及ReflectiveMethodInvocation,通过生成的拦截器集合生成拦截器链,然后链式调用,这就实现了Aop功能

ProxyCreatorSupport专注于生成代理,具体使用在ProxyFactoryBean中,将在下一章讲解

上一篇 下一篇

猜你喜欢

热点阅读