美文网首页Spring源码分析Spring AOP
4.SpringAop之ProxyFactoryBean

4.SpringAop之ProxyFactoryBean

作者: 土豆肉丝盖浇饭 | 来源:发表于2018-01-25 11:01 被阅读5次

    1.类继承关系

    image

    2.解析

    ProxyFactoryBean就是具体我们生成一个代理类的入口,是一个工厂类,先看看怎么使用这个类生成代理对象
    先给上我的Demo代码 ProxyFactoryBean demo

    文件结构

    在xml中的配置如下

     <bean id="helloService" class="com.scj.demo.aop.HelloServiceImpl"/>
    
        <bean id="testAfterAdvice" class="com.scj.demo.aop.TestAfterAdvice"/>
    
        <bean id="testAroundAdvice" class="com.scj.demo.aop.TestAroundAdvice"/>
    
        <bean id="testBeforeAdvice" class="com.scj.demo.aop.TestBeforeAdvice" />
    
        <bean id="regexpMethodPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
            <property name="advice" ref="testBeforeAdvice"/>
            <property name="patterns">
                <list>
                    <value>.*hello</value>
                </list>
            </property>
        </bean>
    
        <bean id ="aop" class="org.springframework.aop.framework.ProxyFactoryBean">
            <property name="interfaces" value="com.scj.demo.aop.HelloService"/>
            <property name="target" ref="helloService"/>
            <property name="interceptorNames">
                <list>
                    <value>testBeforeAdvice</value>
                    <value>testAfterAdvice</value>
                    <value>testAroundAdvice</value>
                </list>
            </property>
        </bean>
    

    我们需要在ProxyFactoryBean中配置我们的代理接口(连接点),目标对象,通知,通知器或者拦截器
    配置的通知,会自动转换为Adivisor,配上永远匹配的Pointcut

    @Service("integtareService")
    public class IntegrateService {
    
        @Resource(name = "aop")
        private HelloService helloService;
    
        public void  test(){
            helloService.hello("scj");
        }
    
    }
    

    在IntegrateService注入了HelloService接口,接口实现使用ioc容器中名字为aopbean,也就是我们定义的ProxyFactotyBean

    测试代码如下

    System.out.println("Aop 声明式注入");
    IntegrateService integrateService =applicationContext.getBean(IntegrateService.class);
    integrateService.test();
    

    结果为

    Aop 声明式注入
    test before
    around before
    helloscj
    around after
    after ...
    

    可以看到代理生效了,注入的是我们配置的代理对象

    从上面的配置可以看到,

    前面的铺垫已经ok,我们以ProxyFactoryBean为入口,一步一步把整个代理生成的流程串起来
    因为ProxyFactoryBean是一个工厂bean,我们从它的getObject方法看起

    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();
        }
    }
    

    这个方法的一开始会初始化通知器链,把相应的Adivisor加到AdvisedSupport里到advisors中去
    然后判断是singletonbean还是prototypebean,对应做不同处理。
    但是最终创建代理对象都是调用getProxy(createAopProxy())来实现 ,createAopProxy()来自父类ProxyCreatorSupport

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

    通过ProxyCreatorSupport得到AopProxy后,调用它的getProxy方法得到正真的代理对象。
    得到代理对象之后,我们的工作就完成了,就像使用目标对象一样使用就好了。

    ProxyFactoryBean虽说是声明式的,但是它对每一个接口都需要我们去配置一个ProxyFactotyBean,我们一般不会用这个来做Aop,更多的是希望只要配置Advisor之后Spring自动帮我们把代理生成了,这就需要我们之后讲的DefaultAdvisorAutoProxyCreator来实现

    Spring中把特定功能委托给其他类或者父类实现,看起来很酷炫,这个模式叫做MixIn 或者 组合模式,以后写代码也可以使用下这种模式

    相关文章

      网友评论

        本文标题:4.SpringAop之ProxyFactoryBean

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