Spring AOP 代理对象的生成 part3

这一节我们探究一下在Spring AOP中目标对象的代理对象的生成过程。
我们会设计到三个主要的类:
ProxyFactoryBean
ProxyCreatorSupport
AdvisedSupport

从上到下时继承的关系。为便于区分我们称之为子类ProxyFactoryBean,父类ProxyCreatorSupport和祖类AdvisedSupport。

生成代理对象过程从子类ProxyFactoryBean开始的。
这个一个FactoryBean,我们会在配置文件中配置这个bean,通过这个bean获取代理对象的。因为的他名字就是代理工厂Bean。
获取代理对象是通过getObject方法,我们把对目标对象的增强都封装在了这个方法中。

@Override
    public Object getObject() throws BeansException {
        initializeAdvisorChain();
        if (isSingleton()) {
            return getSingletonInstance();
        }
        else {
            if (this.targetName == null) {
                logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
                        "Enable prototype proxies by setting the 'targetName' property.");
            }
            return newPrototypeInstance();
        }
    }

在这个方法开始的时候,有一个方法initializeAdvisorChain,这个是用来初始化通知器链的方法。

一、初始化通知器链的过程

在初始化通知器链的过程时,spring会读取配置文件,获得通知器链的名字,然后根据名字,通过getBean方法,获得它的实例。
然后将实例保存起来,具体的保存时通过下面的这个方法:

addAdvisorOnChainCreation(advice, name);
private void addAdvisorOnChainCreation(Object next, String name) {
        // We need to convert to an Advisor if necessary so that our source reference
        // matches what we find from superclass interceptors.
        Advisor advisor = namedBeanToAdvisor(next);
        if (logger.isTraceEnabled()) {
            logger.trace("Adding advisor with name '" + name + "'");
        }
        addAdvisor(advisor);
    }

主要调用的方法就是addAdvisor(advisor);很简单。
不过这个方法是祖类AdvisedSupport中定义的。
AdvisedSupport中有一个Linkedlist属性,用于存放通知器。它是私有的。

public void addAdvisor(Advisor advisor) {
        int pos = this.advisors.size();
        addAdvisor(pos, advisor);
    } 
@Override
    public void addAdvisor(int pos, Advisor advisor) throws AopConfigException {
        if (advisor instanceof IntroductionAdvisor) {
            validateIntroductionAdvisor((IntroductionAdvisor) advisor);
        }
        addAdvisorInternal(pos, advisor);
    }
private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException {
        Assert.notNull(advisor, "Advisor must not be null");
        if (isFrozen()) {
            throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
        }
        if (pos > this.advisors.size()) {
            throw new IllegalArgumentException(
                    "Illegal position " + pos + " in advisor list with size " + this.advisors.size());
        }

        this.advisors.add(pos, advisor);
        updateAdvisorArray();
        adviceChanged();
    }

此时就将通知器保存进了AdvisedSupport中,后面还会用到,具体是下一篇博客。

通知器链初始完成之后,就开始生成代理对象了。

二、生成代理对象

在getObject 中我们看到,根据目标对象是否是单例提供两种生成代理对象的方式。
我们首先看单例模式的情况:getSingletonInstance();

 private synchronized Object getSingletonInstance() {
        if (this.singletonInstance == null) {
            this.targetSource = freshTargetSource();
            if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                // Rely on AOP infrastructure to tell us what interfaces to proxy.
                Class<?> targetClass = getTargetClass();
                if (targetClass == null) {
                    throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                }
                setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
            }
            // Initialize the shared singleton instance.
            super.setFrozen(this.freezeProxy);
            this.singletonInstance = getProxy(createAopProxy());
        }
        return this.singletonInstance;
    }

主要看最后一行this.singletonInstance = getProxy(createAopProxy());代码。
getProxy的实现如下:

protected Object getProxy(AopProxy aopProxy) {
        return aopProxy.getProxy(this.proxyClassLoader);
}

此时有一个类AopProxy,这个类就是spring中负责生产代理对象的类。准确的说这是一个接口。具体工作是由他的实现类完成的。
在Spring中还提供了一个生成这个AopProxy实现类的工厂类:AopProxyFactory 。其实这个AopProxyFactory 也是一个接口。
所以,在这个地方spring使用的时抽象工厂模式。在spring中AopProxyFactory 只有一个实现类DefaultAopProxyFactory。
AopProxy由两个直接的实现类JdkDynamicAopProxy和ObjenesisCglibAopProxy。
总结一下就是:由DefaultAopProxyFactory负责生成两个AopProxy。由JdkDynamicAopProxy和ObjenesisCglibAopProxy负责生成代理对象。

逻辑表述完毕。我们看下源码实现。

这行代码有一个参数createAopProxy()

this.singletonInstance = getProxy(createAopProxy());

我们看下这个方法createAopProxy()
这个方法定义在 父类ProxyCreatorSupport中了

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

我们解释一下,createAopProxy 这个方法就是创建AopProxy,刚才我们表述过,这个是由AopProxyFactory 工厂创建的。
Ok,我们需要继续看getAopProxyFactory()这个方法,获取AopProxyFactory 工厂的方法。

public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }

这个方法很简单,返回本身的aopProxyFactory对象,这个又是什么呢,我们看ProxyCreatorSupport父类的构造函数:

public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

我们发现就是默认的DefaultAopProxyFactory 工厂类。
那么createAopProxy(this); 这个方法就是DefaultAopProxyFactory 类中的方法了。
我们看下这个方法:

@Override
    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() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

在这个方法中我们看到了两个AopProxy实现类的创建过程。
我们还看这个createAopProxy(this);他传递的参数时this
他是自然ProxyCreatorSupport这个类的一个实例。
由于ProxyCreatorSupport是AdvisedSupport 子类,所以这个参数就可以理解了。为什么要传递这个AdvisedSupport 参数我们等下说明。
现在我们假设创建的类是JdkDynamicAopProxy;

这个类是用来创建代理对象的,我们看下这个方法aopProxy.getProxy(this.proxyClassLoader);
那么getProxy 就是JdkDynamicAopProxy中的方法:

@Override
    public Object getProxy(ClassLoader classLoader) {
    ……
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

这个是上一博客讲的jdk生成代理对象的方法。现在我们来看此处的三个参数:
第一个ClassLoader ,AOP使用了一个默认的ClassLoader 。事实上我们使用任何一个类都可以得到ClassLoader 。这个目标对象无关。
proxiedInterfaces 这个参数就是需要从AdvisedSupport中获取的。在这个getSingletonInstance() 方法最开始时,有一个方法 setInterfaces,这个方法在AdvisedSupport中定义,就是将接口信息保存进了AdvisedSupport中list中。这也是在createAopProxy(this);方法传递this,即传递AdvisedSupport的原因。
第三个this:此处的this 就是JdkDynamicAopProxy,因为这个类实现了InvocationHandler这个接口这就意味着 在JdkDynamicAopProxy 还有一个invoke方法。我们稍后分析这个方法,在下一篇博客中分析。以我们刚才的分析,此时生成了目标对象的代理对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值