版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
文章目录
JdkRegexpMethodPointcut
可以设定正则表达式,只要目标的方法名匹配正则表达式,就会应用到通知。
示例代码
目标接口:
package com.csdn.springaop.target;
public interface MyInterface {
public void method1();
public void method1(String s);
public void method2() throws Exception ;
public void test1();
}
目标:
package com.csdn.springaop.target;
public class Target implements MyInterface {
public void method1() {
System.out.println("Target method1");
}
public void method1(String s) {
System.out.println("Target method1"+s);
}
public void method2() throws Exception {
throw new Exception("Target method2 Error!");
}
public void test1() {
System.out.println("Target test1");
}
}
通知:
package com.csdn.springaop.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice{
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("MyBeforeAdvice");
}
}
测试代码:
@Test
public void test4() {
Target target=new Target();
MyBeforeAdvice myBeforeAdvice=new MyBeforeAdvice();
ProxyFactory proxyFactory =new ProxyFactory();
proxyFactory.setTarget(target);
JdkRegexpMethodPointcut pc=new JdkRegexpMethodPointcut();
pc.setPattern(".*method.*");
DefaultPointcutAdvisor advisor=new DefaultPointcutAdvisor(pc,myBeforeAdvice);
proxyFactory.addAdvisor(advisor);
MyInterface target1=(MyInterface)proxyFactory.getProxy();
System.out.println("运行method()");
target1.method1();
System.out.println("运行method(\"one\")");
target1.method1("one");
System.out.println("运行method(\"two\")");
target1.method1("two");
System.out.println("运行test1方法");
target1.test1();
}
输出结果:
运行method1()
MyBeforeAdvice
Target method1
运行method1("one")
MyBeforeAdvice
Target method1one
运行method1("two")
MyBeforeAdvice
Target method1two
运行test1方法
Target test1
可以看到,方法名带“method”的方法都应用到了MyBeforeAdvice通知,方法名为“test1”的方法没有应用到通知,因为它不能匹配正则表达式匹配的方法名字。
JdkRegexpMethodPointcut 的方法
- setPattern(String pattern)
- setPatterns(String… patterns)
通过可变长度的参数,传入多个pattern - setExcludedPattern(excludedPattern)
传入一个pattern,不过是设置排除匹配正则表达式的方法,也就是说不符合正则表达式的方法才会应用通知。 - **setExcludePatterns(String… excludedPatterns) **
设置多个pattern,运行时会排除符合这多个正则表达式的方法
NameMatchMethodPointcut
使用方法名进行匹配,它有3个方法:
- addMethodName(String name)
向NameMatchMethodPointcut中加入一个方法名,符合加入的方法名的方法会引用到通知 - setMappedName(String name)
重新设置NameMatchMethodPointcut中匹配的方法名集合为一个方法名,符合参数传入的方法名的方法会应用到通知 - setMappedNames(String… mappedNames)
设置匹配的方法名集合,在参数给定集合中的存在的方法会应用到通知
示例代码
将上面示例的测试代码部分修改成:
@Test
public void test5() {
Target target=new Target();
MyBeforeAdvice myBeforeAdvice=new MyBeforeAdvice();
ProxyFactory proxyFactory =new ProxyFactory();
proxyFactory.setTarget(target);
NameMatchMethodPointcut pc=new NameMatchMethodPointcut();
pc.addMethodName("method1");
DefaultPointcutAdvisor advisor=new DefaultPointcutAdvisor(pc,myBeforeAdvice);
proxyFactory.addAdvisor(advisor);
MyInterface target1=(MyInterface)proxyFactory.getProxy();
System.out.println("运行method1()");
target1.method1();
System.out.println("运行method1(\"one\")");
target1.method1("one");
System.out.println("运行method1(\"two\")");
target1.method1("two");
System.out.println("运行test1方法");
target1.test1();
}
和上一个示例的测试代码比较起来,只是切入点换成了NameMatchMethodPointcut ,结果是:
扫描二维码关注公众号,回复:
7198197 查看本文章
运行method1()
MyBeforeAdvice
Target method1
运行method1("one")
MyBeforeAdvice
Target method1one
运行method1("two")
MyBeforeAdvice
Target method1two
运行test1方法
Target test1
AnnotationMatchingPointcut
应用特定注解修饰的方法和类。
示例代码
创建一个注解:
package com.csdn.springaop.target;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyAnnotation {
}
在目标类Target上应用注解MyAnnotation
@MyAnnotation
public class Target implements MyInterface {
测试代码:
@Test
public void test6() {
Target target=new Target();
MyBeforeAdvice myBeforeAdvice=new MyBeforeAdvice();
ProxyFactory proxyFactory =new ProxyFactory();
proxyFactory.setTarget(target);
AnnotationMatchingPointcut pc=new AnnotationMatchingPointcut(MyAnnoation.class);
DefaultPointcutAdvisor advisor=new DefaultPointcutAdvisor(pc,myBeforeAdvice);
proxyFactory.addAdvisor(advisor);
MyInterface target1=(MyInterface)proxyFactory.getProxy();
System.out.println("运行method1()");
target1.method1();
System.out.println("运行method1(\"one\")");
target1.method1("one");
System.out.println("运行method1(\"two\")");
target1.method1("two");
System.out.println("运行test1方法");
target1.test1();
}
运行结果:目标类的所有方法都应用到了通知
运行method1()
MyBeforeAdvice
Target method1
运行method1("one")
MyBeforeAdvice
Target method1one
运行method1("two")
MyBeforeAdvice
Target method1two
运行test1方法
MyBeforeAdvice
Target test1
如果我们再修改下上面的测试代码,创建AnnotationMatchingPointcut类型实例时,构造方法使用AnnotationMatchingPointcut(Class classAnnotationType,Class methodAnnotationType),应用指定注解的方法才应用通知,运行结果就成了
运行method1()
Target method1
运行method1("one")
Target method1one
运行method1("two")
Target method1two
运行test1方法
Target test1
没有一个方法应用到通知,因为没有一个方法上有指定的注解
AspectJExpressionPointcut
这是一个与AspectJ相关的切入点实现类,使用AspectJ表达式作为切入规则,因此需要AspectJ支持。
示例代码:
引入AspectJ的依赖:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
测试代码:
@Test
public void test7() {
Target target=new Target();
MyBeforeAdvice myBeforeAdvice=new MyBeforeAdvice();
ProxyFactory proxyFactory =new ProxyFactory();
proxyFactory.setTarget(target);
AspectJExpressionPointcut pc=new AspectJExpressionPointcut();
pc.setExpression("execution(* method*(..))");
DefaultPointcutAdvisor advisor=new DefaultPointcutAdvisor(pc,myBeforeAdvice);
proxyFactory.addAdvisor(advisor);
MyInterface target1=(MyInterface)proxyFactory.getProxy();
System.out.println("运行method1()");
target1.method1();
System.out.println("运行method1(\"one\")");
target1.method1("one");
System.out.println("运行test1方法");
target1.test1();
}
运行结果:
运行method1()
MyBeforeAdvice
Target method1
运行method1("one")
MyBeforeAdvice
Target method1one
运行test1方法
Target test1
可以看到,跟“method”匹配的两个方法都应用到了通知,test1方法没有应用到通知。