持续创作,加速成长!这是我参与「掘金日新计划 · 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>
切面的定义
切面的定义方式有两种,一种是通过注解的方式,另一种则是通过表达式的方式。
基于注解的方式
-
定义一个用于标记切入点的注解
-
定义切面逻辑处理类,切入点的定义方式有以下几种:
@Around:环绕式切面通知时间点最早。@Before:业务方法执行前通知,作用于@Around之后。@After:方法调用后通知。@AfterReturning:在方法返回值返回后进行通知。@AfterThrowing:在抛出异常后进行通知。
基于注解有两种写法如下:
- 切面测试类
@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";
}
}
- 测试结果
注:切入点类分两种
ProceedingJoinPoint、JoinPoint,其中ProceedingJoinPoint仅对切入方式为@Around时才允许使用,其他切入方式仅允许使用JoinPoint参数或者不使用参数。
基于表达式的方式
基于表达式的调用方式也比较简单,唯一不同的地方就在于切入点的声明,所以在这里我们只需要声明一个切入点即可。
- 声明切入点
- 切面测试类
@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方法。
切面不生效的情况
由于AOP框架是通过代理(Proxy)的方式实现的,所以在使用切面的时候必须要保证切入点是由代理对象进行调用的,如下图所示中的testReturn()方法虽然有添加切入点注解,但实际是直接调用而不是通过代理对象调用,所以是不会被运用到切面处理的。这种情况如果我们想要让所调用方法的切面生效,只需要按照上面的例子,在类中注入对象本身,再使用对象引用的方式进行调用。
总结
切面编程能够帮我们很好的处理各种业务节点前后统一功能的实现,在Spring框架中也被大量运用,例如事务处理、日志拦截、权限控制等等。AOP切面编程在实际业务当中可能运用的也不会很多,各位开发者还是得根据业务设计合理使用。