概述
在Spring-AOP 静态普通方法名匹配切面案例中 StaticMethodMatcherPointcutAdvisor中,仅能通过方法名定义切点,这种描述方式不够灵活,假设目标类中有多个方法,切满足一定的命名规范,使用正则表达式进行匹配就灵活多了。
RegexpMethodPointcutAdvisor是正则表达式方法匹配的切面实现类,该类已经是功能齐全的实现类,一般情况下无需扩展该类。
实例
代码已托管到Github—> https://github.com/yangshangwei/SpringMaster
业务类 Waiter和Seller
package com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor;
public class Waiter {
public void greetTo(String name) {
System.out.println("Waiter Greet to " + name);
}
public void serverTo(String name) {
System.out.println("Waiter Server to " + name);
}
}
package com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor;
public class Seller {
public void greetTo(String name) {
System.out.println("Seller Greet to " + name);
}
}
前置增强
package com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class GreetBeforeAdivce implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
// 输出切点
System.out.println("Pointcut:" + target.getClass().getName() + "."
+ method.getName());
String clientName = (String) args[0];
System.out.println("How are you " + clientName + " ?");
}
}
配置文件
RegexpMethodPointcutAdvisor是正则表达式方法匹配的切面实现类,该类已经是功能齐全的实现类,一般情况下无需扩展该类。
直接使用RegexpMethodPointcutAdvisor,通过配置的方式为目标类定义一个切面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!-- 配置切面:静态正则表达式方法匹配切面 -->
<!-- Waiter目标类 -->
<bean id="waiterTarget" class="com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor.Waiter"/>
<!-- Seller目标类 -->
<bean id="sellerTarget" class="com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor.Seller"/>
<!-- 前置增强 -->
<bean id="greetBeforeAdvice" class="com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor.GreetBeforeAdivce"/>
<!-- 切面 -->
<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:advice-ref="greetBeforeAdvice"
p:pattern=".*greet.*" > <!-- 向切面注入一个前置增强 , 用正则表达式定义目标类全限定方法名的匹配模式串 。-->
</bean>
<!-- 通过父bean,配置公共的信息 -->
<bean id="parent" abstract="true"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="regexpAdvisor"
p:proxyTargetClass="true"/>
<!-- waiter代理 -->
<bean id="waiter" parent="parent" p:target-ref="waiterTarget"/>
<!-- seller代理 -->
<bean id="seller" parent="parent" p:target-ref="sellerTarget"/>
</beans>
单元测试
package com.xgj.aop.spring.advisor.RegexpMethodPointcutAdvisor;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RegexpMethodPointcutAdvisorTest {
@Test
public void test() {
// 加载配置文件,启动容器
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:com/xgj/aop/spring/advisor/RegexpMethodPointcutAdvisor/conf-advisor.xml");
// 从容器中获取Bean
Waiter waiter = ctx.getBean("waiter", Waiter.class);
Seller seller = ctx.getBean("seller", Seller.class);
// 调用业务方法
waiter.greetTo("XiaoGongJiang");
waiter.serverTo("XiaoGongJiang");
seller.greetTo("XiaoGongJiang");
}
}
运行结果
可见,Waiter和 Seller的greetTo()都成功的织入了切面,Waiter.serverTo()没有被织入切面。
RegexpMethodPointcutAdvisor除了pattern和advice属性外 ,还有另外两个属性
patterns: 如果只有一个匹配串模式,这可以使用pattern属性配置,如果需要定义多个匹配模式穿,就需要使用patterns属性了, 这些匹配模式串是“或"的关系。order:切面织入时对应的顺序
正则表达式语法
正则表达式工具 RegexBuddy
可以使用RegexBuddy简单的测下,如果匹配,下方会以黄色标注。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。