切入点和切入点表达式(AOP面向切面编程)

1 篇文章 0 订阅
1 篇文章 0 订阅

https://blog.csdn.net/keda8997110/article/details/50747923/

AOP面向切面编程。通过预编译方式和运行期动态代理实现程序功能的统一维护的技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高了开发效率。
简单来说, 就是在程序运行期间, 在不修改源码的情况下, 对正在运行的方法进行功能增强,添加或删除某些功能。

在使用AOP进行切面开发的过程中,需要配置一下我们的切入点,也就是配置一下我们要增强哪些方法。配置切入点,就需要编写切入点表达式,通过切入点表达式去找到我们的切入点(被增强方法)。

配置切入点
@Pointcut注解:

通过@Pointcut注解配置切入点。该注解作用在方法上。我们在编写增强方法的时候,切入点的名字就是该方法的方法名。
@Pointcut注解中的切入点表达式,就是我们要对哪些方法进行增强。

/**
 * 配置切入点,编写切入点表达式. 我们要增强什么
 */
@Pointcut("execution(* com.xue.demo.service.impl.*.*(..))")
public void pointCut() {
}

/**
 * 前置通知
 */
@Before(value = "pointCut()")
public void beforeRun() {
    System.out.println("执行之前执行,前置通知");
}

这里我们对com.xue.demo.service.impl包下的所有类的所有的方法进行了增强。我们在调用com.xue.demo.service.impl包下的所有类的所有的方法前,会先执行我们的前置通知方法。

对切入点的配置,还有其他的方式。

如果我们要配置两个切入点,比如需要对两个包下的方法进行增强,我们就需要编写两个切入点表达式。因此,我们的切入点表达式支持使用&&、|| 和 !。

我们可以配置两个切入点,用两个不同的方法名。然后我们再配置一个切入点,该切入点的切入点表达式就是那两个切入点的方法名组合而成的。

@Pointcut("execution(* com.xue.demo.service.impl.*.ru*(..))")
public void pointCutR() {
}
@Pointcut("execution(* com.xue.demo.service.impl.*.ju*(..))")
public void pointCutJ() {
}
@Pointcut("pointCutJ() || pointCutR()")
public void pointCut() {
}

这里配置了两个切入点,方法分别是pointCutR()和pointCutJ()。这两个方法分别对com.xue.demo.service.impl包下的所有类的ru开头的方法和com.xue.demo.service.impl包下的ju开头的方法进行了增强。我们可以再配置一个切入点,该切入点的表达式就是pointCutR()和pointCutJ()两个方法的方法名。使用 || 连接。表示 com.xue.demo.service.impl包下的所有类的ru开头的方法和ju开头的方法都会被增强。

切入点表达式:

切入点表达式主要为了帮助我们增强我们要增强的方法。根据切入点表达式,可以找到我们要增强的方法。个人理解,感觉就像是一个导航,通过切入点表达式,就可以知道哪些方法需要被增强。
切入点表达式由 访问修饰符 返回值 报名 类名 方法名 以及我们的方法的参数组成。其中访问修饰符是可以省略不写的。返回值我们可以根据我们要增强的方法进行选择。也可以使用通配符 * ,表示所有返回类型的方法全部都被增强。
切入点表达式中的包名,表示了指定包下的类需要被增强。包名也可以使用通配符 * 表示。
类名和方法名也都可以使用我们的通配符 * 表示。但是方法中的参数,我们使用的是(…)表示多个参数。还可以指定增强方法的参数类型。

在进行切入点配置的时候,支持多种配置方式。可以根据我们的需求,对指定的方法进行增强。

execution:用于匹配方法执行的连接点。
within:用于匹配指定类型内的方法执行。
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配。
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配。
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法。
@within:用于匹配所以持有指定注解类型内的方法。
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解。
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行。
@annotation:用于匹配当前执行方法持有指定注解的方法。

举例:

@Pointcut("execution(* com.xue.demo.service.impl.*.*(..))")
public void point() {
}

该切入点表达式可以对对指定的方法进行增强的切入点方法

@Pointcut("within(com.xue.demo.service.impl.*)")
public void point() {
}

该切入点表达式可以对指定的类的中的所有的方法进行增强

@Pointcut("this(com.xue.demo.service.EmployeeService)")
public void point() {
}

用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配

@Pointcut("target(com.xue.demo.service.EmployeeService)")
public void point() {
}

用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配

@Pointcut("args(String)")
public void point() {
}

用于匹配当前执行的方法传入的参数为指定类型的执行方法;

@Pointcut("@within(com.xue.demo.annotation.Custom)")
public void point1() {
}

任何目标对象对应的类型持有Custom注解的类方法;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用。

@Pointcut("@target(com.xue.demo.annotation.Custom)")
public void point2() {
}

任何目标对象持有Custom注解的类方法;必须是在目标对象上声明这个注解,在接口上声明的对它不起作用

@Pointcut("@args(com.xue.demo.annotation.Custom)")
public void point3() {
}

任何一个只接受一个参数的方法,且方法运行时传入的参数持有注解 com.xue.demo.annotation.Custom;动态切入点,类似于arg指示符;

@Pointcut("@annotation(com.xue.demo.annotation.Custom)")
public void point4() {
}

使用“@annotation(注解类型)”匹配当前执行方法持有指定注解的方法;注解类型也必须是全限定类型名;

文章中有不对的地方,务必指正,互相学习,共同进步。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值