Spring源码分析Spring AOP

4.SpringAop之ProxyFactoryBean

2018-01-25  本文已影响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 或者 组合模式,以后写代码也可以使用下这种模式

上一篇 下一篇

猜你喜欢

热点阅读