美文网首页程序员
Spring事物之——AbstractSingletonProx

Spring事物之——AbstractSingletonProx

作者: 丑星星 | 来源:发表于2017-09-06 23:28 被阅读0次

        接下来的几篇文章我们要讨论一下Spring事物的实现原理。在讨论Spring事物的过程中,我们以分析Spring事物中几个关键类的方式来了解Spring事物是如何实现的。本文的基础是建立在对Spring Aop有深入理解的前提下,如果小伙伴们对Spring Aop的原理有疑问,请看一下《Spring AOP --JDK动态代理方式》这边文章。
        言归正传,我们来看一下本篇文章的重点,也是分析Spring事物过程中的第一个关键类:AbstractSingletonProxyFactoryBean。从类名上,我们可以猜的出AbstractSingletonProxyFactoryBean是一个抽象类,实现了FactoryBean。对Spring比较熟悉的小伙伴们应该对FactoryBean不陌生,希望大家能知道FactoryBean的区别,这里我们就不多说了,不清楚的小伙伴可以查一下其他资料。我们可以从AbstractSingletonProxyFactoryBean的定义证实我们的猜想:

    public abstract class AbstractSingletonProxyFactoryBean extends ProxyConfig
            implements FactoryBean<Object>, BeanClassLoaderAware, InitializingBean
    

    既然AbstractSingletonProxyFactoryBean实现了FactoryBean接口,我们就来看一下FactoryBean的getObject()方法,看一下AbstractSingletonProxyFactoryBean是什么对象的工厂:

        public Object getObject() {
            if (this.proxy == null) {
                throw new FactoryBeanNotInitializedException();
            }
            return this.proxy;
        }
    

    getObject() 方法返回的是AbstractSingletonProxyFactoryBean本身持有的proxy对象,这个对象是怎么产生的,我们可以看到proxy对象是在afterPropertiesSet()方法中赋值的,afterPropertiesSet()方法是InitializingBean接口的方法,InitializingBean接口是一个Bean在生命周期中的一个重要的接口,实现了这个接口的Bean在实例化属性赋值完之后,spring会调用其afterPropertiesSet()方法作为钩子方法。我们先来看看AbstractSingletonProxyFactoryBean的afterPropertiesSet()做了哪些事情:

        @Override
        public void afterPropertiesSet() {
            if (this.target == null) {
                throw new IllegalArgumentException("Property 'target' is required");
            }
            if (this.target instanceof String) {
                throw new IllegalArgumentException("'target' needs to be a bean reference, not a bean name as value");
            }
            if (this.proxyClassLoader == null) {
                this.proxyClassLoader = ClassUtils.getDefaultClassLoader();
            }
            //创建一个ProxyFactory 对象
            ProxyFactory proxyFactory = new ProxyFactory();
            //设置代理工厂要产生的代理的前置通知
            if (this.preInterceptors != null) {
                for (Object interceptor : this.preInterceptors) {
                    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
                }
            }
    
            // Add the main interceptor (typically an Advisor).添加一个通知,createMainInterceptor()是一个抽象方法,交给子类实现
            proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
            //设置代理工厂要产生的代理的后置通知
            if (this.postInterceptors != null) {
                for (Object interceptor : this.postInterceptors) {
                    proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(interceptor));
                }
            }
    
            proxyFactory.copyFrom(this);
    
            TargetSource targetSource = createTargetSource(this.target);
            proxyFactory.setTargetSource(targetSource);
    
            if (this.proxyInterfaces != null) {
                proxyFactory.setInterfaces(this.proxyInterfaces);
            }
            else if (!isProxyTargetClass()) {
                // Rely on AOP infrastructure to tell us what interfaces to proxy.
                proxyFactory.setInterfaces(
                        ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
            }
            //产生对象的前置方法,这里是个空方法,子类可以通过实现这个方法来改变proxyFactory的配置
            postProcessProxyFactory(proxyFactory);
    
            this.proxy = proxyFactory.getProxy(this.proxyClassLoader);
        }
    

        看过《Spring AOP --JDK动态代理方式》这边文章的同学对ProxyFactory应该不会陌生,ProxyFactory能够根据配置的代理对象、通知(Advice)来生成代理对象。这一点清楚后我们再回过头来看一下afterPropertiesSet()究竟干了什么。首先,方法创建了一个ProxyFactory的对象。然后将AbstractSingletonProxyFactoryBean设置的前置通知添加到ProxyFactory的通知链中。然后通过createMainInterceptor()获得一个通知,将该通知添加到通知链中。createMainInterceptor()是一个抽象方法,由子类去实现。随后,又将AbstractSingletonProxyFactoryBean设置的后置通知添加到ProxyFactory的通知链中。做完通知链添加动作之后,又将AbstractSingletonProxyFactoryBean配置的各种属性赋值到proxyFactory中,具体哪些属性这里不多说了。做完这一系列动作之后,又调用了 postProcessProxyFactory(proxyFactory);方法,这个方法是一个模板方法,作为proxyFactory产生代理对象前的前置方法,提供修改proxyFactory的机会。最后通过调用proxyFactory的getProxy(ClassLoader classLoader)方法产生代理对象。
        到这里我们看到了Spring设计中经常使用的一种设计模式,模板模式。afterPropertiesSet()方法其实为AbstractSingletonProxyFactoryBean提供了产生proxy对象的模板,而proxy代理对象的通知是由子类产生的。在产生代理对象之前,模板方法通过开放postProcessProxyFactory(ProxyFactory proxyFactory)方法,给子类修改代理对象配置的机会。AbstractSingletonProxyFactoryBean生成完proxy对象之后就会一直持有该对象,等待调用者调用工厂方法。
        我们来总结一下AbstractSingletonProxyFactoryBean的作用:AbstractSingletonProxyFactoryBean作为一个单例工厂,定义了产生代理对象的模板,AbstractSingletonProxyFactoryBean产生的代理对象的具体代理内容交由子类定义。
        AbstractSingletonProxyFactoryBean的具体作用和原理我们分析完了,Spring事物其实是通过AbstractSingletonProxyFactoryBean定义的模板来实现事物代理对象创建的。具体细节我们在接下里的几篇文章中会继续讨论。本篇内容很简单,也可以作为之前Spring相关文章的一个复习内容。

    相关文章

      网友评论

        本文标题:Spring事物之——AbstractSingletonProx

        本文链接:https://www.haomeiwen.com/subject/gpzvjxtx.html