利用aop我們可以實現業務代碼與系統級服務例如日志記錄、事務及安全相關業務的解耦,使我們的業務代碼更加干凈整潔。
最近在做數據權限方面的東西,考慮使用切面對用戶訪問進行攔截,進而確認用戶是否對當前數據有訪問權限,而我們的項目是springboot項目,所以花時間研究了下springboot下切面的實現。
1、首先加入相關maven依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、編寫控制器
@RestController public class HelloController { @RequestMapping("/add1") public String addData1(String deviceId) { return "success"; } @RequestMapping("/add2") public String addData2(String deviceId) { return "success"; } @RequestMapping("/add3") public String addData3(String deviceId) { return "success"; } }
3、配置切面
@Aspect
@Component
public class TestAspect {
@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..))")
public void addAdvice(){}
@Around("addAdvice()")
public Object Interceptor(ProceedingJoinPoint pjp){
Object result = null;
Object[] args = pjp.getArgs();
if(args != null && args.length >0) {
String deviceId = (String) args[0];
if(!"03".equals(deviceId)) {
return "no anthorization";
}
}
try {
result =pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
}
這樣下來我們就實現了一個簡單切面,在切面中實現自己的數據安全認證,此處只做一個簡單判斷,測試如下:


4、但是這樣的切面不夠靈活,所以我們添加一個自定義注解
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
}
5、修改切面類
@Aspect
@Component
public class TestAspect {
@Pointcut("execution(public * com.example.demo.controller.HelloController.add*(..)) && @annotation(com.example.demo.controller.MyAnnotation)" )
public void addAdvice(){}
@Around("addAdvice()")
public Object Interceptor(ProceedingJoinPoint pjp){
Object result = null;
Object[] args = pjp.getArgs();
if(args != null && args.length >0) {
String deviceId = (String) args[0];
if(!"03".equals(deviceId)) {
return "no anthorization";
}
}
try {
result =pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
return result;
}
}
6、修改控制器,給需要切面的方法上加上注解
@RestController
public class HelloController {
@MyAnnotation
@RequestMapping("/add1")
public String addData1(String deviceId) {
return "success";
}
@RequestMapping("/add2")
public String addData2(String deviceId) {
return "success";
}
@RequestMapping("/add3")
public String addData3(String deviceId) {
return "success";
}
}
通過自定義注解,我們可以靈活的添加切面,在需要使用切面的方法上添加注解,測試如下:



實際開發中我們可以將"execution(public * com.example.demo.controller.HelloController.add*(..)) && @annotation(com.example.demo.controller.MyAnnotation)"改為"execution(public * com.example.demo.controller.*.*(..)) && @annotation(com.example.demo.controller.MyAnnotation)",這樣在controller包下,只有我們加上@MyAnnotation注解的方法切面方法才會起作用。
