@Pointcut的使用

@PointCut 概览

这个注解包含两部分,PointCut表达式PointCut签名。表达式是拿来确定切入点的位置的,说白了就是通过一些规则来确定,哪些方法是要增强的,也就是要拦截哪些方法。

注意:

由于是动态代理的实现方法,所以不是所有的方法都能拦截得下来

对于JDK代理只有public的方法才能拦截得下来。

对于CGLIB只有public和protected的方法才能拦截。

 

支持的表达式类型

@PointCut(...........)括号里面那些就是表达式。括号里支持的类型有:

execution: 匹配连接点

within: 某个类里面

this: 指定AOP代理类的类型

target:指定目标对象的类型

args: 指定参数的类型

bean:指定特定的bean名称,可以使用通配符(Spring自带的)

@target: 带有指定注解的类型

@args: 指定运行时传的参数带有指定的注解

@within: 匹配使用指定注解的类

@annotation:指定方法所应用的注解

  • execution:

execution的匹配方法,大多数时候都会用这个来定义pointcut:

格式:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
            throws-pattern?)

execution(方法修饰符(可选)  返回类型  类路径 方法名  参数  异常模式(可选)) 

其中后面跟着“?”的是可选项括号中各个pattern分别表示:

  • 修饰符匹配(modifier-pattern?)
  • 返回值匹配(ret-type-pattern): 可以为*表示任何返回值, 全路径的类名等
  • 类路径匹配(declaring-type-pattern?)
  • 方法名匹配(name-pattern):可以指定方法名 或者 代表所有, set 代表以set开头的所有方法
  • 参数匹配((param-pattern)):可以指定具体的参数类型,多个参数间用“,”隔开,各个参数也可以用"" 来表示匹配任意类型的参数,"…"表示零个或多个任意参数。
    如(String)表示匹配一个String参数的方法;(
    ,String) 表示匹配有两个参数的方法,第一个参数可以是任意类型,而第二个参数是String类型。
  • 异常类型匹配(throws-pattern?)

除了返回类型,方法名还有参数之外,其他都是可选的

下面给几个例子:

1)execution(public * *(..))——表示匹配所有public方法
2)execution(* set*(..))——表示所有以“set”开头的方法
3)execution(* com.xyz.service.AccountService.*(..))——表示匹配所有AccountService接口的方法
4)execution(* com.xyz.service.*.*(..))——表示匹配service包下所有的方法
5)execution(* com.xyz.service..*.*(..))——表示匹配service包和它的子包下的方法

  • within:

是用来指定类型的,指定类型中的所有方法将被拦截是用来指定类型的,指定类型中的所有方法将被拦截

within(com.demo.service.impl.UserServiceImpl) 匹配UserServiceImpl类对应对象的所有方法调用,并且只能是UserServiceImpl对象,不能是它的子对象
within(com.demo…*)匹配com.demo包及其子包下面的所有类的所有方法的外部调用。

  • this:

SpringAOP是基于代理的,this就代表代理对象,语法是this(type),当生成的代理对象可以转化为type指定的类型时表示匹配。

this(com.demo.service.IUserService)匹配生成的代理对象是IUserService类型的所有方法的外部调用

  • target:

SpringAOP是基于代理的,target表示被代理的目标对象,当被代理的目标对象可以转换为指定的类型时则表示匹配。

target(com.demo.service.IUserService) 匹配所有被代理的目标对象能够转化成IuserService类型的所有方法的外部调用。

  • args:

args用来匹配方法参数

args() 匹配不带参数的方法
args(java.lang.String) 匹配方法参数是String类型的
args(…) 带任意参数的方法
args(java.lang.String,…) 匹配第一个参数是String类型的,其他参数任意。最后一个参数是String的同理。

  • @within 和 @target

带有相应标注的所有类的任意方法,比如@Transactional

@within(org.springframework.transaction.annotation.Transactional)
@target(org.springframework.transaction.annotation.Transactional)

  • @annotation:

带有相应标注的任意方法,比如@Transactional

@annotation(org.springframework.transaction.annotation.Transactional)
@within和@target针对类的注解,@annotation针对方法的注解

  • @args:

参数带有相应标注的任意方法,比如@Transactional

@args(org.springframework.transaction.annotation.Transactional)


Pointcut 的使用

可以通过Java注解XML两种方式配置

在多个表达式之间使用 ||,or表示 或,使用 &&,and表示 与,!表示 非

1、XML方式配置

<aop:config>  
    <aop:aspectrefaop:aspectref="aspectDef">  
        <aop:pointcutidaop:pointcutid="pointcut1"expression="execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))"/>  
        <aop:before pointcut-ref="pointcut1" method="beforeAdvice" />  
    </aop:aspect>  
</aop:config>  

2、注解方式

@Component  
@Aspect  
public class AspectDef {  
    // 单表达式
    //@Pointcut("execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))")  
    //@Pointcut("within(com.test.spring.aop.pointcutexp..*)")  
    //@Pointcut("this(com.test.spring.aop.pointcutexp.Intf)")  
    //@Pointcut("target(com.test.spring.aop.pointcutexp.Intf)")  
    //@Pointcut("@within(org.springframework.transaction.annotation.Transactional)")  
    //@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)")

    // 多表达式
    //@Pointcut("cutController() && cutService()")

    @Pointcut("args(String)")  
    public void pointcut1() {  
    }  
    @Before(value = "pointcut1()")  
    public void beforeAdvice() {  
        System.out.println("pointcut1 @Before...");  
    }

 

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
你好!要使用 `@pointcut` 注解,你需要先了解 AOP(面向切面编程)的概念。AOP 是一种编程范式,它允许你在不修改原有代码的情况下,通过将横切关注点(如日志记录、性能统计等)与核心业务逻辑分离开来。 在 Spring 框架中,`@pointcut` 注解用于定义切点(Pointcut),即你想要在程序执行过程中插入横切逻辑的地方。切点可以通过切点表达式(Pointcut Expression)指定,它是一个用于匹配连接点(Join Point)的规则。 下面是一个简单的使用 `@pointcut` 的示例: ```java @Aspect public class LoggingAspect { @Pointcut("execution(* com.example.service.*.*(..))") private void serviceMethods() {} @Before("serviceMethods()") public void logBefore(JoinPoint joinPoint) { System.out.println("Before method: " + joinPoint.getSignature().getName()); } } ``` 这个示例中,我们定义了一个切点 `serviceMethods()`,它匹配 `com.example.service` 包中的所有方法。然后,我们在切点上定义了一个前置通知 `logBefore()`,它会在切点方法执行前被调用,并打印方法名。 注意,上面的代码是一个简化的示例,实际使用中可能需要更复杂的切点表达式和横切逻辑。你可以根据自己的需求来定义切点和通知。 除了 `@Pointcut` 注解,还有其他几个常用的注解用于定义通知,如 `@Before`、`@After`、`@Around` 等,它们分别表示前置通知、后置通知和环绕通知。你可以根据需要选择合适的注解来实现你的横切逻辑。 希望这个简单示例能帮助你理解 `@pointcut` 的使用!如果还有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值