使用Advice拦截目标对象时,默认情况下将拦截目标对象中的所有方法。
在实际应用中,有些情况下需要对目标对象的方法有选择性地进行拦截。
Spring的AOP框架提供了两种拦截器,即Advice和Advisor,其中Advisor就能够实现这种功能。
Advisor是Spring框架AOP组件独有的类型,能够将一个Advice对象和一个切入点关联。
Spring的API中提供了接口Advisor,该接口拥有很多实现类,
本文将学习较常用的NameMatchMethodPointcutAdvisor和RegexpMethodPointcutAdvisor两个实现类。
NameMatchMethodPointcutAdvisor类使用完整的方法名来确定是否应用某一个Advice,
类中常用的setter方法有如下两个:
1、配置Advice对象
Advisor本质上还是使用Advice进行拦截,所以依然需要首先配置Advice实例:
<bean id="logbefore" class="advice.LogBeforeAdvice">
</bean>
<bean id="logafter" class="advice.LogAfterAdvice">
</bean>
<bean id="logaround" class="advice.LogAroundAdvice">
</bean>
<bean id="logthrows" class="advice.LogThrowsAdvice">
</bean>
2、配制NameMatchMethodPointcutAdvisor对象:
<bean id="logbeforeadvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref bean="logbefore"></ref>
</property>
<property name="mappedNames">
<list>
<value>login</value>
<value>viewAll</value>
</list>
</property>
</bean>
每个Advisor只能关联一个Advice,但是可以同时对应多个方法名。
上述配置中将logbefore与login和viewAll方法对应,所以只有调用login和viewAll方法时,才会被logbefore拦截,
而调用其他方法,如register方法,就不会被logbefore拦截。
3、在代理对象中引用Advisor
<span style="white-space:pre"> </span><bean id="serviceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<span style="white-space:pre"> </span><property name="interfaces">
<span style="white-space:pre"> </span><list>
<span style="white-space:pre"> </span><value>service.CustomerService</value>
<span style="white-space:pre"> </span></list>
<span style="white-space:pre"> </span></property>
<span style="white-space:pre"> </span><property name="targetName">
<span style="white-space:pre"> </span><value>service</value>
<span style="white-space:pre"> </span></property>
<span style="white-space:pre"> </span><property name="interceptorNames">
<span style="white-space:pre"> </span><list>
<span style="white-space:pre"> </span><value>logbeforeadvisor</value>
<span style="white-space:pre"> </span><value>logafter</value>
<span style="white-space:pre"> </span><value>logaround</value>
<span style="white-space:pre"> </span><value>logthrows</value>
<span style="white-space:pre"> </span></list>
<span style="white-space:pre"> </span></property>
<span style="white-space:pre"> </span></bean>
上述配置文件中,在代理对象serviceProxy中通过<property name="interceptorNames">使用了名字为logbeforeadvisor的Advisor拦截器,
所以只有在login和viewAll方法调用前,才调用logbefore通知。
同时还未serviceProxy实例指定了三个Advice进行拦截,
也就是说,代理对象可以同时使用Advice和Advisor作于拦截器。
RegexpMethodPointcutAdvisor类
该类能够通过正则表达式将方法与Advice连接起来。
RegexpMethodPointcutAdvisor中常用的setter方法有以下两个:
public void setAdvice(org.aopalliance.aop.Advice advice):指定该Advisor中使用的Advice,该方法与NameMatchMethodPointcutAdvisor中的setAdvice方法相同。
setPatterns(String[] patterns):通过正则表达式指定方法名的集合。
配置实例如下:
<bean id="logafteradvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="logafter"></ref>
</property>
<property name="patterns">
<list>
<value>customer*</value>
</list>
</property>
</bean>
分析上述配置信息可见,RegexpMethodPointcutAdvisor类使用元素<property name="patterns">配置需要连接的方法的正则表达式,
其中的<value>customer*</value>就是匹配方法名的正则表达式,表示方法名必须以customer开头。
上述配置的Advisor实例,将logafter通知于所有以customer开头的方法连接起来,可以作为拦截器使用。