Spring-AOP 静态普通方法名匹配切面操作
程序员文章站
2022-03-09 10:51:49
概述staticmethodmatcherpointcutadvisor代表一个静态方法匹配切面,它通过staticmethodmatcherpointcut来定义切点,并通过类过滤和方法名来匹配所定...
概述
staticmethodmatcherpointcutadvisor代表一个静态方法匹配切面,它通过staticmethodmatcherpointcut来定义切点,并通过类过滤和方法名来匹配所定义的切点.
实例
代码已托管到github—> https://github.com/yangshangwei/springmaster
我们假设我们业务类中 waiter和 seller中都有同名的greetto()方法.
业务类waiter
package com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor; public class waiter { /** * * * @title: greetto * * @description: * * @param name * * @return: void */ public void greetto(string name) { system.out.println("waiter greet to " + name); } /** * * * @title: serverto * * @description: * * @param name * * @return: void */ public void serverto(string name) { system.out.println("waiter server to " + name); } }
业务类seller
package com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor; public class seller { /** * * * @title: greetto * * @description: 和waiter类中的同名的方法,目的是为了验证仅仅织入了waiter类中的greetto方法 * * @param name * * @return: void */ public void greetto(string name) { system.out.println("seller greet to " + name); } }
现在我们希望通过staticmethodmatcherpointcutadvisor定义一个切面,在waiter#greetto()方法调用前织入一个增强,即连接点为waiter#greetto()方法调用前的位置。
切面代码
package com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor; import java.lang.reflect.method; import org.springframework.aop.classfilter; import org.springframework.aop.support.staticmethodmatcherpointcutadvisor; /** * * * @classname: greetingadvisor * * @description: 切面类 * * @author: mr.yang * * @date: 2017年8月18日 下午8:27:52 */ public class greetingadvisor extends staticmethodmatcherpointcutadvisor { private static final long serialversionuid = 1l; /** * 重写matches方法,切点方法匹配规则:方法名为greetto */ @override public boolean matches(method method, class<?> targetclass) { return "greetto".equals(method.getname()); } /** * 默认情况下,匹配所有的类,重写getclassfilter,定义匹配规则 切点类型匹配规则,为waiter的类或者之类 */ public classfilter getclassfilter() { return new classfilter() { @override public boolean matches(class<?> clazz) { return waiter.class.isassignablefrom(clazz); } }; } }
staticmethodmatcherpointcutadvisor 抽象类唯一需要定义的是matches()方法,在默认情况下,该切面匹配所有的类,这里通过覆盖getclassfilter()方法,让它仅匹配waiter类及其子类。
当然,advisor还需要一个增强类的配合 .
我们来定义一个前置增强
package com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor; import java.lang.reflect.method; import org.springframework.aop.methodbeforeadvice; /** * * * @classname: greetbeforeadivce * * @description: 前置增强 * * @author: mr.yang * * @date: 2017年8月18日 下午8:27:40 */ 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 + " ?"); } }
我们使用spring配置来定义切面等信息
<?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.staticmethodmatcherpointcutadvisor.waiter"/> <!-- seller目标类 --> <bean id="sellertarget" class="com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor.seller"/> <!-- 前置增强 --> <bean id="greetbeforeadvice" class="com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor.greetbeforeadivce"/> <!-- 切面 --> <bean id="greetadvicesor" class="com.xgj.aop.spring.advisor.staticmethodmatcherpointcutadvisor.greetingadvisor" p:advice-ref="greetbeforeadvice"/> <!-- 向切面注入一个前置增强 --> <!-- 通过父bean,配置公共的信息 --> <bean id="parent" abstract="true" class="org.springframework.aop.framework.proxyfactorybean" p:interceptornames="greetadvicesor" 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.staticmethodmatcherpointcutadvisor; import org.junit.test; import org.springframework.context.applicationcontext; import org.springframework.context.support.classpathxmlapplicationcontext; /** * * * @classname: staticmethodmatcherpointcutadvisortest * * @description: 测试类 * * @author: mr.yang * * @date: 2017年8月18日 下午8:29:28 */ public class staticmethodmatcherpointcutadvisortest { @test public void test() { // 加载配置文件,启动容器 applicationcontext ctx = new classpathxmlapplicationcontext( "classpath:com/xgj/aop/spring/advisor/staticmethodmatcherpointcutadvisor/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"); } }
运行结果:
我们可以看到切面仅仅织入了wwaiter.greetto()方法调用前的连接点上, waiter.serverto()和seller.greetto()方法并没有织入切面。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。