一、引入依赖

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}");
    }
}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐