切入点2

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44778952/article/details/89483844

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方法没有应用到通知。

猜你喜欢

转载自blog.csdn.net/weixin_44778952/article/details/89483844