springboot+自定义注解实现灵活的切面配置

利用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、配置切面

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@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、但是这样的切面不够灵活,所以我们添加一个自定义注解

  

1

2

3

4

5

6

@Documented 

@Retention(RetentionPolicy.RUNTIME) 

@Target(ElementType.METHOD) 

public @interface MyAnnotation {

     

}

  5、修改切面类

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

@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、修改控制器,给需要切面的方法上加上注解

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@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注解的方法切面方法才会起作用。

发布了58 篇原创文章 · 获赞 206 · 访问量 32万+

猜你喜欢

转载自blog.csdn.net/weixin_39816740/article/details/88529433