欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring-AOP 静态普通方法名匹配切面操作

程序员文章站 2022-06-22 23:23:15
概述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");
	}
}

运行结果:

Spring-AOP 静态普通方法名匹配切面操作

我们可以看到切面仅仅织入了wwaiter.greetto()方法调用前的连接点上, waiter.serverto()和seller.greetto()方法并没有织入切面。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。