AOP概念篇今天介绍Pointcut的公式
通配符中常见的通配符包括
…含义一:表示方法表达式中任意数量的参数
@ servicepublicclasshelloservice { public void sayhi (string name ) system.out.println )、' hi、' name ); }公共void sayhi (string first name,String lastName ) system.out.println('hi,' firstName lastName ); }@pointcut(execution ) public void com.example.junitspringboot.service.hello service.sayhi ) ) ) public voice
连接点:在调用方法之前、调用方法之后、方法抛出异常之后执行程序的特定位置,例如访问类成员或执行异常处理程序块。 类或程序代码的一部分包含具有边界性质的特定点。 这些代码的特定点是连接点。 也可以嵌套其他连接点。 AOP中的Joinpoint有多种类型,包括调用构造方法、设置和获取字段、调用方法、执行方法、处理异常以及初始化类。 Spring仅支持方法执行类型的连接点。 意义2 )在类定义式中,表示任意的子程序包
@ component @ aspectpublicclasssserviceaop { @ pointcut . execution (public void com.example.junitspringboot . hello service @around(pointcut ) ) ) publicobjectbefore ) proceedingjoinpointproceedingjoinpoint ) ) throwstoing returnproceedingjoinpont ) //注意软件包名称package com.example.junitspringboot.service.inner; importorg.spring framework.stereotype.service; @service(innerHelloservice ) (公共类健康服务)公共void sayhi (string first name,String lastName ) system.)。 //注意软件包名称package com.example.junitspringboot.service; public class hello service { public void sayhi (string name ) system.out.println('hi,' name ); }匹配指定的类及其子类
public interface Person { void say (; } @ servicepublicclassmanimplementsperson { @ overridepublicvoidsay ((system.out.println ) ) man ); } @ servicepublicclasswomanimplementsperson { @ overridepublicvoidsay ((system.out.println ) woman ' ); } @ pointcut (within (com.example.junitspringboot.service.Person ) ) )中,接口person的
*匹配任意数量的字符
//com.example.junitspringboot.service包含所有类的所有方法@ pointcut (' within (com.example.junitspringbot.service ) (以' say开头的所有方法@pointcut(execution ) (…) ) ) ) public void pointcut2) ) {} execution中最常用的表达式,指定方法的是什么? 表示不是必须的
执行(modifiers-pattern )? ret-type-pattern de
claring-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*(..))") 任意返回类型方法名称以 say 开头任意参数 @Pointcut("execution(* *(..) throws Exception)") 方法声明抛出 Exception 的任意方法 within指定特定类型、类型中所有的方法都被拦截。
@Pointcut("within(com.example.junitspringboot.service.Person)") Person 类所有外部的方法调用都被拦截 @Pointcut("within(com.example.junitspringboot.service.Person+)") Person 类及其子类所有外部的方法调用都被拦截 @Pointcut("within(com.example.junitspringboot.service..*)" 所有在 com.example.junitspringboot.service 包以及子包下的所有类的所有外部调用方法 thisthis通过判断代理类是否按类型匹配指定类来决定是否和切点匹配。 用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配。 this中使用的表达式必须是类型全限定名,不支持通配符。
public class ServiceAop implements Ordered { @Pointcut("this(com.example.junitspringboot.service.ISwimming)") public void thisPointcut(){} @Before("thisPointcut()") public void before(JoinPoint joinPoint) { System.out.println("before"); } @Override public int getOrder() { return 1; }}// 使用引介使 Man 也实现 ISwimming 接口@Component@Aspectpublic class IntroductionAop implements Ordered { @DeclareParents(value = "com.example.junitspringboot.service.Man", defaultImpl = Swimming.class) public ISwimming swimming; @Override public int getOrder() { return 0; }}// 微信公众号:CoderLipublic interface ISwimming { void swim();}// 微信公众号:CoderLi@Servicepublic class Man implements Person{ @Override public void say() { System.out.println("man"); }} ConfigurableApplicationContext context = SpringApplication.run(JunitSpringBootApplication.class, args); context.getBean(Man.class).say(); ((ISwimming) context.getBean(Man.class)).swim();当我们调用 swim 方法的时候、会被拦截增强。当我们调用 say 方法的时候、同样也会被拦截增强,这个就是 this 会将代理类实现的其他接口的方法也会被拦截增强
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…* 下所有被 AopFlag 修饰的类的所有方法 @args@args匹配被调用的方法上含有参数,且对应的参数类型上拥有指定的注解的情况。
@Pointcut("@args(com.example.junitspringboot.anno.AopFlag)")// 微信公众号:CoderLi@AopFlagpublic class Data {}public interface Person { void say(Data data);} @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 种切点的表达式介绍完毕