当前位置: 首页 > 后端技术 > Java

切入点表达式

时间:2023-04-01 14:16:16 Java

AOPConcepts今天介绍了切入点表达式通配符。常用的通配符如下。含义1:在一个方法表达式中,表示任意数量的参数@ServicepublicclassHelloService{publicvoidsayHi(Stringname){System.out.println("嗨,"+姓名);}publicvoidsayHi(StringfirstName,StringlastName){System.out.println("hi,"+firstName+lastName);}}@Pointcut("execution(publicvoidcom.example.junitspringboot.service.HelloService.sayHi(..))")publicvoidpointcut(){}那么上面的Pointcut表达式可以包含HelloService中的两个连接点。连接点:程序执行的特定位置,如方法调用前后、方法抛出异常后、类成员的访问、异常处理程序块的执行等。一个类或一段程序代码有一些具有边界属性的特定点,代码中的这些特定点就是连接点。它还可以自己嵌套其他连接点。AOP中的Joinpoint可以有多种类型:构造函数调用、字段设置和获取、方法调用、方法执行、异常处理执行、类初始化。Spring只支持方法执行类型的连接点。含义2:在类定义表达式中,表示任意子包@Component@AspectpublicclassServiceAop{@Pointcut("execution(publicvoidcom.example.junitspringboot..HelloService.sayHi(..))")publicvoidpointcut(){}@Around("pointcut()")publicObjectbefore(ProceedingJoinPointproceedingJoinPoint)throwsThrowable{System.out.println("before");返回proceedingJoinPoint.proceed();}}//注意包名packagecom.example.junitspringboot.service.inner;importorg.springframework.stereotype.Service;@Service("innerHelloService")publicclassHelloService{publicvoidsayHi(StringfirstName,StringlastName){System.out.println("嗨,"+firstName+lastName);}}//注意包名packagecom.example.junitspringboot.service;publicclassHelloService{publicvoidsayHi(Stringname){System.out.println("hi,"+name);}}+match给定一个类及其子类publicinterfacePerson{voidsay();}@ServicepublicclassManimplementsPerson{@Overridepublicvoidsay(){System.out.println("人");}}@ServicepublicclassWomanimplementsPerson{@Overridepublicvoidsay(){System.out.println("woman");}}@Pointcut("within(com.example.junitspringboot.service.Person+)")publicvoidpointcut(){}那么接口Person的子类实现的所有方法都会被增强*匹配任意数量的字符//com.example.junitspringboot.service包括所有类Method@Pointcut("within(com.example.junitspringboot.service.*)")publicvoidpointcut1(){}//所有以say开头的方法@Pointcut("execution(*say*(..))")publicvoidpointcut2(){}execution是最常用的表达式,用来指定方法的执行。?表示可选的执行(modifiers-pattern?ret-type-patterndeclaring-type-pattern?name-pattern(param-pattern)throws-pattern?)modifiers-pattern?指示修饰符,例如public、protectedret-type-pattern返回类型,是必需的。如果使用通配符*来表示任何返回类型declaring-type-pattern?表示声明该方法的类。name-pattern表示方法名称。param-pattern表示方法参数,如果使用通配符,表示任意参数throws-pattern?表示方法抛出的异常Execution(public*com.example..say*(..))修饰符为public任何返回类型在com.example包或其子包中,方法名以say任何参数开头@Pointcut("execution(*say*(..))")anyreturntypemethodnamestartswithsayanyparameter@Pointcut("execution(**(..)throwsException)")方法声明任何抛出异常的方法特定类型,并拦截该类型中的所有方法。@Pointcut("within(com.example.junitspringboot.service.Person)")拦截Person类的所有外部方法调用@Pointcut("within(com.example.junitspringboot.service.Person+)")Person类和其子类的所有外部方法调用都被拦截@Pointcut("within(com.example.junitsspringboot.service..*)"com.example.junitsspringboot.service包及子包中所有类的所有外部调用方法thisthis判断是否通过类型判断代理类是否匹配指定类来匹配切入点,用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,可能包含导入的接口和类型匹配。这里使用的表达式必须是完全限定的类型名称,不支持通配符。publicclassServiceAopimplementsOrdered{@Pointcut("this(com.example.junitspringboot.service.ISwimming)")publicvoidthisPointcut(){}@Before("thisPointcut()")publicvoidbefore(JoinPointjoinPoint){System.out.println("之前");}@OverridepublicintgetOrder(){返回1;}}//使用引介使Man也现实ISwimming接口@Component@AspectpublicclassIntroductionAopimplementsOrdered{@DeclareParents(value="com.example.junitspringboot.service.Man",defaultImpl=Swimming.class)publicISwimmingswimming;@OverridepublicintgetOrder(){返回0;}}//微信公众号:CoderLipublicinterfaceISwimming{voidswim();}//微信公众号:CoderLi@ServicepublicclassManimplementsPerson{@Overridepublicvoidsay(){System.out.println("man");}}ConfigurableApplicationContextcontext=SpringApplication.run(JunitSpringBootApplication.class,args);context.getBean(Man.class).say();((游泳)context.getBean(Man.class)).swim();当我们调用swim方法时,它会被拦截和增强。当我们调用say方法时,它也会被拦截和增强。这是这个会实现代理类的方法,其他接口的方法也会被拦截增强的targettarget判断连接点是否匹配,通过类型判断目标类是否匹配指定的类。用于匹配当前目标对象类型的执行方法;注意目标对象的类型是匹配的,所以不包括导入的接口也是类型匹配的;@Pointcut("target(com.example.junitspringboot.service.ISwimming)")也是上面的例子。修改切入点表达式为target,say方法不再拦截增强。args用于匹配参数@Pointcut("args(..)")匹配任何有参数的方法@Pointcut("args()")匹配任何没有参数的方法@target匹配被代理的目标对象对应的类型及其时父类型具有指定的注解@Pointcut("@target(com.example.junitspringboot.anno.AopFlag)&&within(com.example.junitspringboot..*)")匹配包com.example.junitspringboot..*All被AopFlag修饰的所有类的methods@args@args匹配被调用的方法包含参数,对应的参数类型有指定的注解。@Pointcut("@args(com.example.junitspringboot.anno.AopFlag)")//微信公众号:CoderLi@AopFlagpublicclassData{}publicinterfacePerson{voidsay(Datadata);}@within@within当与代理目标对象或其父类型对应的类型具有指定的注释时匹配,但仅当调用具有指定注释的类上的方法时才匹配。@Pointcut("@within(com.example.junitspringboot.anno.AopFlag)&&within(com.example.junitspringboot..*)")在功能上看起来有点像@target。@annotation也是一个常用的注解。用于匹配具有指定注释的方法。@Pointcut("@annotation(com.example.junitspringboot.anno.AopFlag)&&within(com.example.junitspringboot..*)")一个特定于beanSpring的表达式。@Pointcut("bean(man)")拦截bean的所有方法10个切入点表达式介绍完毕