SpringBoot切面编程

412 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

简介

SpringBoot切面编程实际就是SpringBoot整合的AOP切面的具体实现,主要使用AOP代理的方式进行运作,普遍运用于对某些功能统一做切面实现一些共同的附加功能,接下来我们就来看看具体如何使用。

AOP概念

  • 切面(Aspect):以@Aspect注解定义的封装了切入点类。
  • 通知(Advice):给目标方法添加额外操作增强功能。
  • 连接点(JointPoint):连接方法前后过程的一个阶段。
  • 切点(Pointcut):AOP框架实际增强功能的地方。
  • 代理(Proxy):创建代理对象,用于实现切面的整个流程。
  • 织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。

依赖

基于SpringBoot整合AOP实现,需依赖依赖maven包。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

切面的定义

切面的定义方式有两种,一种是通过注解的方式,另一种则是通过表达式的方式。

基于注解的方式

  • 定义一个用于标记切入点的注解 image.png

  • 定义切面逻辑处理类,切入点的定义方式有以下几种:

    • @Around:环绕式切面通知时间点最早。
    • @Before:业务方法执行前通知,作用于@Around之后。
    • @After:方法调用后通知。
    • @AfterReturning:在方法返回值返回后进行通知。
    • @AfterThrowing:在抛出异常后进行通知。

基于注解有两种写法如下: image.png

image.png

  • 切面测试类
@Slf4j
@RestController
public class CarController {

    @Autowired
    private CarController controller;

    @PostMapping("/production")
    public String production(@RequestParam String name) {
        log.info("===>>> {} production ...", controller.testReturn(name));
        return name + " production success";
    }

    @CarAnnotation
    public String testReturn(String name) {
        log.info("===>>> testReturn {}", name);
        return "666";
    }
}
  • 测试结果

image.png

注:切入点类分两种ProceedingJoinPointJoinPoint,其中ProceedingJoinPoint仅对切入方式为@Around时才允许使用,其他切入方式仅允许使用JoinPoint参数或者不使用参数。

基于表达式的方式

基于表达式的调用方式也比较简单,唯一不同的地方就在于切入点的声明,所以在这里我们只需要声明一个切入点即可。

  • 声明切入点

image.png

  • 切面测试类
@Slf4j
@RestController
public class CarController {

    @Autowired
    private CarController controller;

    @PostMapping("/production")
    public String production(@RequestParam String name) {
        log.info("===>>> {} production ...");
        return name + " production success";
    }
}
  • 测试结果 由下图我们不难看出测试的结果于注解的方式都是一样的,只不过我们为了方便日志输出省去了testReturn方法。

image.png

切面不生效的情况

由于AOP框架是通过代理(Proxy)的方式实现的,所以在使用切面的时候必须要保证切入点是由代理对象进行调用的,如下图所示中的testReturn()方法虽然有添加切入点注解,但实际是直接调用而不是通过代理对象调用,所以是不会被运用到切面处理的。这种情况如果我们想要让所调用方法的切面生效,只需要按照上面的例子,在类中注入对象本身,再使用对象引用的方式进行调用。

image.png

总结

切面编程能够帮我们很好的处理各种业务节点前后统一功能的实现,在Spring框架中也被大量运用,例如事务处理、日志拦截、权限控制等等。AOP切面编程在实际业务当中可能运用的也不会很多,各位开发者还是得根据业务设计合理使用。