[转]SpringAOP拦截器的代理机制

  要使用方法名匹配AOP切面编程,需要使用到Spring中的 org.springframework.aop.support.NameMatchMethodPointcutAdvisor这个类,advice 属性定义一个通告类,mappedName定义通告类针对的方法,通告的类需要实现一些特定的接口在特定的时候执行:

   MethodBeforeAdvice :方法之前执行

   AfterReturningAdvice:方法之后执行

   继承 ThrowsAdviceInterceptor:抛出异常之后执行。

AOP代理类通过org.springframework.aop.framework.ProxyFactoryBean实现,属性target 定义需要进行通告的类或接口,属性interceptorNames定义拦截使用的类,返回字符串数组,这样就基本实现了AOP代理。代码如下:

<bean id="methodBeforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice">
			<bean class="com.yxfei.advice.MyBeforeAdvice"></bean>
		</property>
		<property name="mappedName">
			<value>*</value>
		</property>
	</bean>
	<bean id="methodAfterAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice">
			<bean class="com.yxfei.advice.MyAfterAdvice"></bean>
		</property>
		<!-- 拦截方法匹配 -->
		<property name="mappedName">
			<value>query*</value>
		</property>
	</bean>
	<!-- 只能拦截到一个目标类 -->
	<bean id="myService" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="interceptorNames">
			<list>
				<value>methodBeforeAdvisor</value>
				<value>methodAfterAdvisor</value>
			</list>
		</property>
		<property name="target"><!-- 只能拦截到一个目标类 -->
			<bean class="com.yxfei.pointcut.MyPointCut"></bean>
		</property>
	</bean>

其中com.yxfei.advice.MyBeforeAdvice实现 org.springframework.aop.MethodBeforeAdvice接口,而 com.yxfei.advice.MyAfterAdvice实现 org.springframework.aop.AfterReturningAdvice接口;

(前置拦截的类必须实现MethodBeforeAdvice接口,实现其中的before方法。
   后置拦截的类必须实现AfterReturningAdvice接口,实现其中的afterReturning方法。
   前后拦截的类必须实现MethodInterceptor接口,实现其中的invoke方法。

  异常拦截的类必须实现ThrowsAdvice接口,实现其中的afterThrowing方法。)

ProxyFactoryBean只能拦截到一个目标 中,如果要实现拦截多个类,则需要使用
org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator,属性 beanNames配置多个类,返回String数组,通配符*Dao,表示名为Dao结尾的所有类进行拦截。实现代码如下:

<!-- 拦截到多个目标类 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">          
       <property name="interceptorNames">   
           <list>   
               <value>methodBeforeAdvisor</value> 
               <value>methodAfterAdvisor</value>               
           </list>   
       </property>  
       <property name="beanNames"> <!-- 拦截到多个目标类 -->  
           <list>   
               <value>*Dao</value>  
           </list>   
       </property>  
   </bean> 

如果Dao没有接口,直接是实现类,则运行的时候出现“no matching editors or conversion strategy found ”错误。主要是因为Spring在转换时,主要是将代理类转换成接口,而不能转换成实际类。而要拦截的对象*Dao是普通类,没有实现任何接口。

为了解决这个问题,又不想再定义一个接口,需要在BeanNameAutoProxyCreator类里面增加一个属性说明代理类非接口类。

<property name="proxyTargetClass" >
	<value>true</value>
</property>

最终配置:

<!-- 拦截到多个目标类 -->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">          
       <property name="interceptorNames">   
           <list>   
               <value>methodBeforeAdvisor</value> 
               <value>methodAfterAdvisor</value>               
           </list>   
       </property>  
       <property name="beanNames">   
           <list>   
               <value>*Dao</value>  
           </list>   
       </property> 
       <!-- beanNames配置的类没有实现接口(为普通类)时配置这个属性 -->
       <property name="proxyTargetClass" >
           <value>true</value>
       </property> 
</bean> 

猜你喜欢

转载自lehsyh.iteye.com/blog/2186942