1.类继承关系
2.使用
ProxyFactoryBean是我们生成代理对象的一种方式,是一个工厂Bean,先看看怎么使用这个类生成代理对象
先给上我的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中配置我们的代理接口(连接点),目标对象,通知,通知器或者拦截器
配置的通知,会自动转换为Advisor,配上永远匹配的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 ...
可以看到代理生效了,注入的是我们配置的代理对象
3.解析
接下来分析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();
}
}
这个方法的一开始会初始化Advisor链,把相应的Adivisor加到AdvisedSupport里到advisors中去。
然后判断是singletonbean还是prototypebean,对应做不同处理。
最终创建代理对象是调用getProxy(createAopProxy())来实现 ,createAopProxy()来自父类ProxyCreatorSupport
protected Object getProxy(AopProxy aopProxy) {
return aopProxy.getProxy(this.proxyClassLoader);
}
通过ProxyCreatorSupport的createAopProxy()方法得到AopProxy后,调用它的getProxy方法得到真正的代理对象。
在ProxyFactoryBean做的最重要的工作还是配置了Advisor。其他的工作父类都能协助完成。
ioc通过getObject方法得到代理对象之后,就能像使用目标对象一样使用代理对象了。
4.总结
ProxyFactoryBean虽说是声明式的,但是它对每一个接口都需要我们去配置一个ProxyFactotyBean,我们一般不会用这个来做Aop,更多的是希望只要配置Advisor之后Spring自动帮我们把需要生成代理对象的对象全部替换,这就需要我们之后讲的DefaultAdvisorAutoProxyCreator来实现
Spring中把特定功能委托给其他类或者父类实现,看起来很酷炫,这个模式叫做MixIn 或者 组合模式,以后写代码也可以使用下这种模式