Spring源码分析之——AOP动态代理的选择

上一篇《Spring源码分析之——AOP的原理及初始化细节》讲到AOP的原理和细节,这一篇补充一下动态代理的选择代码细节。

我们知道动态代理分两种,JDK动态代理和Cglib动态代理,那么Spring选用的哪个呢?

 

右半部分可以看到AopProxy下面有Cglib和JDK两种,至于创建哪种,是左边工厂DefaultAopProxyFactory负责创建的,带着这个图看源码。

1、后置处理器判断是否需要动态代理,判断的依据是Bean是否有配置Advisor;

2、如果需要代理,则构造ProxyFactory对象;

2、通过ProxyFactory对象的父类方法getAopProxyFactory找到AopProxyFactory对象,默认DefaultAopProxyFactory;

3、通过工厂创建实际的代理对象(createAopProxy);

——就这么简单。

 

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

——从createProxy方法开始看 

// 如果需要代理
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
 
    // Create proxy if we have advice.
    // 怎么判断是否需要代理?这里给出了答案:如果有配置Advisers则需要被代理
    // 这里开始去找Advice,Advisor,如果配置了,同时当前的Bean符合要求,就要动态代理
    // 这里说的符合要求,就是advisor配置的正则表达式是否匹配上
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        // 有顾问的Bean,cacheKey=被代理BeanName
        this.advisedBeans.put(cacheKey, Boolean.TRUE);

        // ★★★★★★ 创建代理 ★★★★★★
        Object proxy = createProxy(
                bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    // 否则,设置不需要顾问
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

protected Object createProxy(
        Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }

    // 首先构造一个ProxyFactory工厂,此工厂提供方法getProxy获取代理对象
    // 但其细节是通过其父类先得到AopProxy的工厂,再通过工厂创建AopProxy,再通过AopProxy得到代理对象
    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());
}

 

org.springframework.aop.framework.ProxyFactory

public Object getProxy(ClassLoader classLoader) {
    // createAopProxy是父类方法
    // 1、先创建AopProxy
    // 2、再创建代理对象
    return createAopProxy().getProxy(classLoader);
}

 

进入父类:

org.springframework.aop.framework.ProxyCreatorSupport

public class ProxyCreatorSupport extends AdvisedSupport {

    private AopProxyFactory aopProxyFactory;

    /**
     * Create a new ProxyCreatorSupport instance.
     */
    public ProxyCreatorSupport() {
        // 默认实现: DefaultAopProxyFactory
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        // 默认AopProxyFactory是:DefaultAopProxyFactory,也只有这一个
        return getAopProxyFactory().createAopProxy(this);
    }

    /**
     * Return the AopProxyFactory that this ProxyConfig uses.
     */
    public AopProxyFactory getAopProxyFactory() {
        // 返回默认的DefaultAopProxyFactory
        return this.aopProxyFactory;
    }
}

 

org.springframework.aop.framework.DefaultAopProxyFactory

// 这段代码有前人解释的很好了
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    //这段代码用来判断选择哪种创建代理对象的方式
    //config.isOptimize()   是否对代理类的生成使用策略优化 其作用是和isProxyTargetClass是一样的 默认为false
    //config.isProxyTargetClass() 是否使用Cglib的方式创建代理对象 默认为false
    //hasNoUserSuppliedProxyInterfaces目标类是否有接口存在 且只有一个接口的时候接口类型不是
    //SpringProxy类型 
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        //上面的三个方法有一个为true的话,则进入到这里
        //从AdvisedSupport中获取目标类 类对象
        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.");
        }
        //判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象
        //如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        //配置了使用Cglib进行动态代理  或者目标类没有接口 那么使用Cglib的方式创建代理对象
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        //上面的三个方法没有一个为true 那使用JDK的提供的代理方式生成代理对象
        return new JdkDynamicAopProxy(config);
    }
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值