SpringAop 什么时候调用jdk动态代理?什么时候调用cglib

1.导入log4j.jar,开启log4j DEBUG模式

2.查看打印日志,可以发现一个重要信息:

2020-03-03 15:13:31,870 DEBUG [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator] - Creating implicit proxy for bean 'userService' with 0 common interceptors and 4 specific interceptors

spring再执行aop时,执行了 AnnotationAwareAspectJAutoProxyCreator 类中的某个方法

 
3.通过 AnnotationAwareAspectJAutoProxyCreator 找到最终执行的是其父类 AbstractAutoProxyCreator 中的 protected Advisor[]  buildAdvisors(String beanName, Object[] specificInterceptors) 方法

4. 重新在 buildAdvisors 这个方法打断点进行调试

5.AbstractAutoProxyCreator 类中发现有一个重要的方法createProxy 如下:

protected Object createProxy(
    Class<?> beanClass, String beanName, 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 (shouldProxyTargetClass(beanClass, beanName)) {
            proxyFactory.setProxyTargetClass(true);
        }
        else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }

    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
    proxyFactory.setTargetSource(targetSource);
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }
    // 核心代码
    return proxyFactory.getProxy(getProxyClassLoader());
}

接着进入 ProxyFactory 中的 getProxy 方法

public Object getProxy(ClassLoader classLoader) {
    // createAopProxy 方法中判断是选择jdk动态代理还是cglib方式代理
    return createAopProxy().getProxy(classLoader);
}

再进入到 ProxyCreatorSupport 中的 createAopProxy 方法

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    // getAopProxyFactory() 返回的是 DefaultAopProxyFactory对象,所以重点还是在 createAopProxy 方法上
    return getAopProxyFactory().createAopProxy(this);
}

6.进入到 DefaultAopProxyFactory 类中的 createAopProxy 方法,这个方法就是如何选择JDK动态代理还是Cglib代理

@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1.config.isProxyTargetClass() 代表 配置中的proxy-target-class属性true/false,默认false
    // 
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        // 目标代理类,如 com.service.impl.UserServiceImpl
        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() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

方法中参数config 是一个 AdvisedSupport类型, AdvisedSupport 继承了 ProxyConfig 类,

public class ProxyConfig implements Serializable {
    // 代表 配置中的proxy-target-class,如果设置true,则使用Cglib方式代理
    private boolean proxyTargetClass = false;

    private boolean optimize = false;

    boolean opaque = false;

    boolean exposeProxy = false;

    private boolean frozen = false;

    // 省略部分代码
    
}

猜你喜欢

转载自www.cnblogs.com/caoxb/p/12406005.html