要使用方法名匹配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>