Spring与AOP系列四:自动代理生成器

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>

参考:动力节点视频课程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值