spring 核心与源码解析(3):AOP如何使用

AOP,面向切面编程,是Spring的另一核心。
在剖析AOP的实现原理前,需要先对如何使用AOP做一番探索,本节仍然使用spring boot作为实验框架。
首先说明AOP的使用场景:日志记录,事务记录等。
即可以看出,AOP的使用方式,采取类似注入式的模式,在某个方法执行前或者执行后,首先执行AOP中规定的代码。
这里涉及到两个性质不同的方法区分,普通方法和AOP中的方法。AOP中的方法会在普通方法执行时执行,那么这个AOP方法为什么不融合到普通方法中呢?因为AOP方法可以被复用。
那么事不宜迟,首先看一个例子:

//controller
@RestController
public class HealthCheckController {
    @RequestMapping(value ="/health" ,method = RequestMethod.GET)
    public String health_check(){
        System.out.println("health");
        return "ok";
    }
}

//aspect
@Aspect
@Component
public class ControllerAspect {
    @Pointcut("execution(* com.example.source.controller..*(..)) ")
    public void controllerMethodPointcut(){}

    @Before("controllerMethodPointcut()")
    public void Interceptor(){
        System.out.println("method start");
    }
}

在spring boot启动后,调用/health接口后就会输出

method start 
health

这是因为,我们在ControllerAspect 中定义了切入点——HealthCheckController,针对HealthCheckController中的任意方法调用,一开始都会先调用ControllerAspect 中的Interceptor()方法,在执行HealthCheckController中的具体方法。

那么如何理解上述注解中各参数的含义?

切入点(Pointcut)的注解

光凭猜,大概也能猜出上述代码片段中@Pointcut的含义:定位哪些方法需要执行AOP方法。
那么@Pointcut的作用就是定义需要执行AOP方法的方法了,这些方法我们称为切入点
那么@Pointcut的注解的具体参数也就是让我们配置如何找到那些需要执行AOP方法的方法。
大体上来说,@Pointcut里可以使用以下几个参数:

execution()
@annotation()
this()
args()
@args()
target()
@target()
within()
@within()

execution()

最常用,直接定义那些方法需要AOP方法。
其完整的格式是:
execution([modifiers-pattern] ret-type-pattern [declaring-type-pattern] name-pattern(param-pattern)[throws-pattern])
其中,
modifiers-pattern:修饰符匹配,如public,private
ret-type-pattern:返回值匹配,如String
declaring-type-pattern:类路径匹配,如 com.example.source
name-pattern:方法名匹配,如Test*(表示以Test开始的方法)
param-pattern:参数匹配,如String
throws-pattern:异常类型匹配
一个完整的execution()写法如下:

@Pointcut("execution(" +
          "public " +
          "String " +
          "com.example.source.controller.HealthCheckController " +         ".health_check" +
          "(..))")

分别对应了上面的参数。
上述代码时一开始的样例@Pointcut("execution(* com.example.source.controller..*(..)) ")的变体,效果不变。
关于execution()可参考:execution()注解参考

@annotation()

通过对execution()的语法解析我们发现,execution()是直接匹配实体方法名的,如果想匹配注解,则无能为力。幸好@annotation()就是干这个的。
@annotation()括号中需要填入注解类,比如:
@annotation(org.springframework.web.bind.annotation.RequestMapping))那么就是关联到被RequestMapping注解的方法。
需要注意的是@annotation()定位到方法一级。

@within和@target针对类的注解,@annotation是针对方法的注解

剩下的几个参数抛几个链接
args()和@args()
@target和@within
@within @annotion @target 的区别

切面的时机

主要是指在切入点之前,之后,还是其他顺序执行。
上面的代码中,用@Before表示在切入点之前,先执行AOP方法,然后在执行普通方法,如果使用@After,那么就表示先执行普通方法,在执行AOP方法。
该类注解共有五种:@Before,@After,@AfterReturning,@AfterThrowing,@Around。
参考spring AOP pointcut 详细用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值