Spring Aop,参数绑定

目前所有的spring文章一律使用spring 4.2.4,包括前面的三篇

在前一篇中,代码里有一些@PointCut、@Before等的基本应用代码,而这次,我们将一起学习一下aop中的参数绑定、在此之前,我们先定义一个最基本的bean

@Component
public class HelloWorld {

	public void sayHello (Data param){
		System.out.println("Hello World! -> " + param.name);
	}
	
}

 在这个bean中、sayHello(Data)即我们要进行aop的方法、它有一个类型为Data的参数、Data也很简单

public class Data {
	
	public String name;
	
	public Data (String name){
		this.name = name;
	}

}

接下来定义切面

@Aspect
@Component
public class HelloWorldAspect {
	
	@Before(value = "execution(* bindData.HelloWorld.sayHello(*)) && args(param2)")
	private void beforeSayHello (Data param2){
		System.out.println("this is before advice! -> " + param2.name);
		param2.name = "change";
	}
	
}

为了能使大家更好的理解、我特意没有将所有的参数均命名为param~~~

 首先说明一点、sayHello(Data param)方法的参数名与切面中的args参数名完全没有关系。注意,我说的是参数名,而不是参数类型没关系。

下面我们逐一介绍上面@Before(value = "execution(* bindData.HelloWorld.sayHello(*)) && args(param2)")

扫描二维码关注公众号,回复: 692946 查看本文章

@Before:表示前置通知。

value:匹配切点。

execution:声明具体的切点;此处表示取bindData包下HelloWorld类的sayHello方法、sayHello方法有且仅有一个参数,该方法可以返回任意的值。

args:匹配参数;在这里,param2首先匹配beforeSayHello方法中的param2参数,注意,这里是匹配名称相同的参数,然后取得param2的类型,为Data,表示匹配的sayHello(*)方法中的参数类型必须为Data,否则不予匹配。

 最后,我们进行测试,当然还是全注解模式:

@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = "bindData")
public class AopConfig {

	@Test
	public void testBeforeSayHello (){
		ApplicationContext ctx = new AnnotationConfigApplicationContext(AopConfig.class);
		Data data = new Data("no change");
		HelloWorld hw = ctx.getBean(HelloWorld.class);
		hw.sayHello(data);
	}
	
}

 结果为

this is before advice! -> no change
Hello World! -> change

 这样一来,我们就能实现在前置通知中改变被切方法的参数值了

还有一点需要注意:

it’s worth pointing out that this won’t work for generic collections. So you cannot define a pointcut like this:

@Before("execution(* ..Sample+.sampleGenericCollectionMethod(*)) && args(param)")
public void beforeSampleMethod(Collection<MyType> param) {
    // Advice implementation
}

 意思是不支持范型集合,不要像上面这样使用

猜你喜欢

转载自zk-chs.iteye.com/blog/2275122
今日推荐