1.自动代理生成器
前面代码中所使用的代理对象,均是由ProxyFactoryBean代理工具类生成的。而该代理工具类存在着如下缺点:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册目标对象 -->
<bean id="someService" class="com.bjpowernode.aop11.SomeServiceImpl"/>
<bean id="someService2" class="com.bjpowernode.aop11.SomeServiceImpl"/>
<!-- 注册切面:通知 -->
<bean id="myAdvice" class="com.bjpowernode.aop11.MyAfterReturningAdvice"/>
<!-- 注册切面:顾问 -->
<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myAdvice"/>
<property name="mappedNames" value="doFirst"/>
</bean>
<bean id="myAdvisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myAdvice"/>
<property name="mappedNames" value="doSecond"/>
</bean>
<!-- 注册自动代理生成器 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<!--
当前的代码存在两个问题:
1)若存在多个目标对象,就需要使用多次ProxyFactoryBean来创建多个代理对象,这会使配置文件变得臃肿,不便于管理
2)用户真正想调用的是目标对象,而真正可以调用的却是代理对象,这不符合正常的逻辑
以上这两个问题,均为ProxyFactoryBean类的功能太简单引起的。
-->
</beans>
(1)一个代理对象只能代理一个Bean,即如果有两个Bean同时都要织入同一个切面,这时,不仅要配置这两个Bean,即两个目标对象,同时还要配置两个代理对象。
(2)在客户类中获取Bean时,使用的是代理类的id,而非我们定义的目标对象Bean的id。我们真正想要执行的应该是目标对象。从形式上看,不符合正常的逻辑。
(1)默认advisor自动代理生成器
DefaultAdvisorAutoProxyCreator代理的生成方式是,将所有的目标对象与Advisor自动结合,生成代理对象。无需给生成器做任何的注入配置。注意,只能与Advisor配合使用。
注意,只需要修改配置文件中的代理生成配置,及测试类中的通过getBean()获取的bean的id为目标类beanId即可。
<!-- 注册自动代理生成器 -->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
(2)Bean名称自动代理生成器
DefaultAdvisorAutoProxyCreator会为每一个目标对象织入所有匹配的Advisor,不具有选择性,且切面只能是顾问Advisor。而BeanNameAutoProxyCreator的代理生成方式是,根据bean的id,来为符合相应名称的类生成相应代理对象,且切面既可以是顾问Advisor又可以是通知Advice。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册目标对象 -->
<bean id="someService" class="com.lmm.aop12.SomeServiceImpl"/>
<bean id="someService2" class="com.lmm.aop12.SomeServiceImpl"/>
<!-- 注册切面:通知 -->
<bean id="myAdvice" class="com.lmm.aop12.MyAfterReturningAdvice"/>
<!-- 注册切面:顾问 -->
<bean id="myAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myAdvice"/>
<property name="mappedNames" value="doFirst"/>
</bean>
<bean id="myAdvisor2" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="myAdvice"/>
<property name="mappedNames" value="doSecond"/>
</bean>
<!-- 注册自动代理生成器 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="someService"/>
<property name="interceptorNames" value="myAdvisor"/>
</bean>
<!--
DefaultAdvisorAutoProxyCreator存在三个问题:
1)不能选择目标对象
2)不能选择切面类型,切面只能是advisor
3)不能选择advisor,所以advisor均将被作为切面织入到目标方法
-->
</beans>
参考:动力节点视频课程