一、引入依赖
web和aop是必须的,fastjson只是为了输出方便;
<!-- web依赖-->
<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>
<!-- json工具包-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
二、定义切面
定义步骤:
(1)、切面类加@Aspect 、@Service注解,告诉springboot这是一个切面类,帮我管起来;
(2)、定义切点@Pointcut;
(3)、定义切入点切入的时机及完成的功能(@Around、@Before、@After、@AfterReturning、@AfterThrowing);
1.基于注解拦截
注解:@PermissionAnnotation
@Service
@Aspect
public class PermissionFirstAdvice {
@Pointcut("@annotation(com.example.demo.anot.PermissionAnnotation)")
private void permissionCheck() {
}
@Around("permissionCheck()")
public Object permissionCheckFirst(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("第一个切面");
return joinPoint.proceed();
}
}
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PermissionAnnotation {
}
其中joinPoint.proceed()执行目标方法,如果没有调用,则不执行目标方法;
proceed传参数的方法可以动态的改变传入目标方法的参数,
2.基于表达式拦截
表达式:* com.example.demo.controller..*.*(..)
第一个 * 号的位置:表示返回值类型,* 表示所有类型。
包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,在本例中指 com.example.demo.controller.包、子包下所有类的方法。
第二个 * 号的位置:表示类名,* 表示所有类。
*(..):这个星号表示方法名,* 表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
@Component
@Aspect
public class ControllerAdvice {
@Pointcut("execution(* com.example.demo.controller..*.*(..))")
public void chtrollerPict(){
}
@Around("chtrollerPict()")
public Object permissionCheckFirst(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("controllerAdvice");
return joinPoint.proceed();
}
}
3、切点多个表达式或注解
多个表达式之间使用 ||,or表示 或,使用 &&,and表示 与,!表示 非
@Pointcut("execution(* com.example.demo.controller..*.*(..))||@annotation(com.example.demo.anot.PermissionAnnotation)")
三、测试
同时满足上述两个切点条件(注解和controller包),如需改变连个切入点的执行顺讯,再切面类上加@Order(0)注解,数字越小,执行越靠前;
package com.example.demo.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.anot.PermissionAnnotation;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping(value = "/permission")
public class TestController {
@RequestMapping(value = "/check", method = RequestMethod.POST)
@PermissionAnnotation
public JSONObject getGroupList(@RequestBody JSONObject request) {
System.out.println("方法执行");
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
}