你们是否在用aop时经常看到这些东西------->@Before("execution(* test.*.*(..))) 这种东西是切点函数, execution叫做切入点指示符,它有很多种类:execution,within,this,target,args,bean(我们只要讲最为常用的execution) execution:英译中是执行的意思 切入点指示符后面写的这些正则一样的东西是切入点表达式
切入函数=切入点指示符+切入点表达式 ;
切入点表达式:(execution) : (修饰符(可省略) 返回值类型 包名(可省略).类名(可省略).方法名(形参名)) 所以至少得有三参数:返回值类型,方法名,形参名
execution除了英语中是执行的意思,那么在aop中它是什么意思了?
它的作用:使被它修饰的方法插入到切入点表达式所指向的方法中(即根据方法名和参数寻找目标类中的方法,然后对其增强).(也就是说execution是一个在文件中寻找目标方法的切点指示符,然后把它下面的(修饰的)方法增添到目标方法前面或者后面,亦或者阻止目标方法方法的执行(实际看目标方法使用什么注解:@after,@before@around))
你们是否懂了点关于切入点表达式了,不懂的话请看下面的代码
package test;
import org.springframework.stereotype.Component;
目标类1:组件类:主要类
@Component
public class test {
public void test1(String name,String does) {
System.out.println(name+does);
}
}
import org.springframework.stereotype.Component;
目标类2
@Component
public class test1 {
public void test(String one,String two,String three) {
System.out.println(one+two+three);
}
}
切面类:增强类:通知类
@Aspect
public class aspect {
@Before("execution( * *(..))") 我这里execution写了必要的三点 返回值类型,方法名,形参
对于返回值---->*代表所有类型的返回值
对于方法名---->同理上
对于形参------->..代表所有类型的形参,同时也表示不计较参数数量(另外*在形参中只代表一个任意类型的形参*,*用逗号隔开的表示允许获取两个任意类型的形参)
execution的形参是没有多大作用的(但是你必须得匹配参数数量与目标方法所带参数量一致,当然你也可以用..来规避这个问题)
为什么说execution的参数没多大作用了?
(指示符仅有execution的条件下)因为execution的作用根据方法和参数数量找到目标方法,然后对目标方法进行加强,而并不是为了获取目标方法信息,所以execution只要有形参就ok了,但是如果我们想获取目标方法的参数,那么我们必须加上args()切入指示符.即如果它所修饰的方法(即加强方法或者又叫通知方法)已经带参了,那么excution就带不动它了,如果你在没有添加args()切入指示符的情况下,execution是会报错的,如下图:
因为它所带的方法只能是无参的,execution带参那么必须添加args(one,two)..此处的one,two必须与加强方法(通知方法)所带的参数一致.
private void test() {
System.out.println("我是一个切入点");
}
}
配置
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
运行类;测试类import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ac {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
test t=ac.getBean(test.class);
test1 t1=ac.getBean(test1.class);
t.test1("林先生", "打代码");
t1.test("1", "2","3");
}
}
输出的结果:
另外一个问题:如果execution修饰的方法带参,使用args()的情况
@Aspect
public class aspect {
@Before("execution(* *(..))"+"&&args(a,b)")
private void test(String a,String b) {
System.out.println("获取目标方法参数a:"+a);
System.out.println("我是一个切入点");
System.out.println("获取目标方法参数b:"+b);
}
}
}
结果输出:
好了今天的切入指示符学习到这里了.......