我们一直使用ProxyFactoryBean来显式的创建AOP代理但是在很多场合这种方式将会使编写配置文件的工作量大大增加由于要从ProxyFactoryBean获得代理对象也会使应用和Spring之间的耦合度增加下面介绍使用Spring提供的自动代理机制来解决这类问题
使用BeanNameAutoProxyCreator
Spring提供的BeanNameAutoProxyCreator类允许我们通过Bean的name属性来指定代理的Bean它暴露了javalangString[]类型的beanNames和 interceptorNames属性beanNames可以指定被代理的Bean名字列表支持*通配符例如*DAO表示所有名字以DAO结尾的BeaninterceptorNames指定通知(Advice)列表或者通知者(Advisor)列表
下面通过一个例程来演示如何使用BeanNameAutoProxyCreator在例子中有两个BeanTestBeanA和BeanB并在TestMain类中的main方法中调用其MyMethod()方法自动代理将会在方法调用前自动的执行配置的前置通知输出提示信息
新建一个名字为AOP_Test的工程添加Spring的IoC和AOP库后新建一aoptest包再分别创建两个类TestBeanA和BeanB添加MyMethod()方法代码如下
代码查看源代码copy to clipboard打印
/**
*
*/
packageaoptest;
/**
*@authorzhangyong
*
*/
publicclassTestBeanA{
publicvoidMyMethod(){
Systemoutprintln(thisgetClass()getName()
+MyMethod()isrun!);
}
}
代码查看源代码copy to clipboard打印
/**
*
*/
packageaoptest;
/**
*@authorzhangyong
*
*/
publicclassBeanB{
publicvoidMyMethod(){
Systemoutprintln(thisgetClass()getName()
+MyMethod()isrun!);
}
}
再创建前置通知类BeforeAdvice
代码查看源代码copy to clipboard打印
/**
*
*/
packageaoptest;
importjavalangreflectMethod;
importorgspringframeworkaopMethodBeforeAdvice;
/**
*@authorzhangyong
*
*/
publicclassBeforeAdviceimplementsMethodBeforeAdvice{
publicvoidbefore(MethodmethodObject[]argsObjecttarget)
throwsThrowable{
Systemoutprintln(methodgetName()+()将要运行!);
}
}
最后创建含有main方法的测试类TestMain
代码查看源代码copy to clipboard打印
/**
*
*/
packageaoptest;
importorgntextApplicationContext;
importorgntextsupportClassPathXmlApplicationContext;
/**
*@authorzhangyong
*
*/
publicclassTestMain{
publicstaticvoidmain(String[]args){
ApplicationContextac=newClassPathXmlApplicationContext(
applicationContextxml);
TestBeanAbeanA=(TestBeanA)acgetBean(TestBeanA);
beanAMyMethod();
BeanBbeanB=(BeanB)acgetBean(BeanB);
beanBMyMethod();
}
}
在配置文件中配置Bean和自动代理Bean完成后代码如下
代码查看源代码copy to clipboard打印
<?xmlversion=encoding=UTF?>
<beans…………>
<beanid=TestBeanAclass=aoptestTestBeanA/>
<beanid=BeanBclass=aoptestBeanB/>
<beanid=BeforeAdviceclass=aoptestBeforeAdvice></bean>
<beanclass=orgspringframeworkaopframeworkautoproxy
BeanNameAutoProxyCreator>
<propertyname=beanNames>
<list>
<value>Test*</value>
</list>
</property>
<propertyname=interceptorNames>
<list>
<value>BeforeAdvice</value>
</list>
</property>
</bean>
</beans>
运行主类输出结果如下
可以看到在主类TestMain中我们是直接从Spring IoC容器中获取收管Bean而不是像以前那样从ProxyFactoryBean中获取代理但是我们的前置通知BeforeAdvice仍然在TestBeanA对象的MyMethod()方法执行前被触发这说明我们的自动代理正在工作
使用DefaultAdvisorAutoProxyCreator
DefaultAdvisorAutoProxyCreator允许我们只需定义相应的Advisor通知者就可以完成自动代理配置好DefaultAdvisorAutoProxyCreator受管Bean后它会自动查找配置文件中定义的Advisor并将它们作用于所有的Bean
修改例程的配置文件使用DefaultAdvisorAutoProxyCreator来完成自动代理完成后配置文件代码如下(本例完整工程代码见例程)
代码查看源代码copy to clipboard打印
<?xmlversion=encoding=UTF?>
<beans……>
<beanid=TestBeanAclass=aoptestTestBeanA/>
<beanid=BeanBclass=aoptestBeanB/>
<beanid=BeforeAdviceclass=aoptestBeforeAdvice/>
<beanclass=orgspringframeworkaopframeworkautoproxy
DefaultAdvisorAutoProxyCreator/>
<beanclass=orgspringframeworkaopsupportNameMatchMethod
PointcutAdvisor>
<propertyname=adviceref=BeforeAdvice/>
<propertyname=mappedNames>
<list>
<value>*Method*</value>
</list>
</property>
</bean>
</beans>
运行主类输出结果如下