springboot通过注解的形式集成aop切面实现签名认证(token验证,权限认证)内附源码地址

说明 **本文是通过springboot注解的方式集成aop切面,让验证模块可以在项目中更灵活的配置。**注解的方式集成aop切面在实际使用中只需要将注解标注在需要执行aop逻辑的方法上即可实现调用。使用起来方便快捷,原始配置aop切面一般都会标注为某个package包下方的所有类中的方法,而实际业务中可能并不是这样的,注解的方式就是为了应对这种情况,能更灵活的控制aop切面。

本文项目地址https://github.com/gwy572294624/springboot_aspect_verify
项目地址

在这里插入图片描述

使用到的jar包

<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>

配置注解

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TokenVerify {

    String value() default "";

}

@Target 用来标注注解可以被用在哪些地方,该注解中的参数是可以放多个,我们是用他来进行签名验证,只使用到了方法,当然也可以加个ElementType.TYPE 可以将注解放在类上,标注当前类中的所有方法都会执行(但是测试过程中直接标注在类上并不会触发下面的方法都执行aop处理逻辑!!!!)。所以aop集成注解的形式应该只支持注解标注方法上。
@Retention 该注解是标注的生命周期,定义的注解那一般情况下肯定是运行时一直用的,所以一般都会选择RUNTIME。
1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
@Documented 指明修饰的注解,可以被例如javadoc此类的工具文档化,只负责标记,没有成员取值。

想深入了解可以移步@Target、@Retention、@Documented注解简介

配置切面类,切入配置好的注解

@Aspect
@Component
@Slf4j
public class TokenAspect {

    @Pointcut("@annotation(com.aspect.config.TokenVerify)")
    public void tokenAspect() {

    }

        @Around("tokenAspect()")
    public Object beforePointcut(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("  切面类  ---!");
        try{
            //获取RequestAttributes
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            //从获取RequestAttributes中获取HttpServletRequest的信息
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
            String data = request.getHeader("Authorization");
            if (ObjectUtils.isEmpty(data)){
                return JSON.toJSONString("token - null");
            }
            //业务逻辑通过token查询验证  
            //-------
            
            
            
            //验证完成后调用 触发aop前置的方法 并返回处理完成的结果
            Object result = joinPoint.proceed();
            return result;
        }catch (Exception e){
            e.printStackTrace();
            return JSON.toJSONString("签名不合法");
        }
    }
    }

验证

@RestController
@RequestMapping(value ="/test/aop/verify")
public class TestController {



    @TokenVerify
    @RequestMapping("/methodOne")
    public String methodOne(){
        System.out.println("新增用户  ----- ");
        return "新增成功";
    }

    @RequestMapping("/methodTwo")
    public String methodTwo(){
        System.out.println("删除用户  ----- ");
        return "删除成功";
    }
}

请求http://127.0.0.1:8080/test/aop/verify/methodOne 拦截
请求http://127.0.0.1:8080/test/aop/verify/methodTwo成功

@RestController
@TokenVerify
@RequestMapping(value ="/testtwo/aop/verify")
public class TestTwoController {


    @RequestMapping("/methodOne")
    public String methodOne(){
        System.out.println("新增用户  ----- ");
        return "新增成功";
    }

    @RequestMapping("/methodTwo")
    public String methodTwo(){
        System.out.println("删除用户  ----- ");
        return "删除成功";
    }
}

请求http://127.0.0.1:8080/testtwo/aop/verify/methodOne 成功
请求http://127.0.0.1:8080/testtwo/aop/verify/methodTwo成功

注解扩展

//当然部分业务逻辑可能涉及到每个注解所对应到方法有其他附加值,每个方法有不相同 例如 我们现在需要通过aop加入系统操作日志,每个方法操作的信息不一样,有新增有修改,这样的话我们可以使用注解的value标注,

@TokenVerify("我在methodOne上")
    @RequestMapping("/methodOne")
    public String methodOne(){
        System.out.println("新增用户  ----- ");
        return "新增成功";
    }

怎么取呢

//切面类中加入

  MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            TokenVerify tokenVerify = signature.getMethod().getDeclaredAnnotation(TokenVerify.class);
            String value = tokenVerify.value();
            System.out.println("==注解@TokenVerify的value==" + value);

//完整代码展示

@Around("tokenAspect()")
    public Object beforePointcut(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("  切面类  ---!");
        try{
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            TokenVerify tokenVerify = signature.getMethod().getDeclaredAnnotation(TokenVerify.class);
            String value = tokenVerify.value();
            System.out.println("==注解@TokenVerify的value==" + value);
            //获取RequestAttributes
            RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            //从获取RequestAttributes中获取HttpServletRequest的信息
            HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
            String data = request.getHeader("Authorization");
            if (ObjectUtils.isEmpty(data)){
                return JSON.toJSONString("token - null");
            }
            //业务逻辑通过token查询验证
            //-------



            //验证完成后调用触发aop前置的方法 并返回处理完成的结果
            Object result = joinPoint.proceed();
            return result;
        }catch (Exception e){
            e.printStackTrace();
            return JSON.toJSONString("签名不合法");
        }
    }

以上,希望本文可以帮到你。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring Boot可以使用注解实现AOP(面向切面编程)。AOP是一种编程范式,它将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,以便更好地实现模块化和复用性。 在Spring Boot中,可以使用@Aspect注解来定义切面,使用@Pointcut注解来定义切点,使用@Before、@After、@Around等注解来定义通知。通过这些注解的组合,可以实现对方法的前置、后置、环绕等操作。 例如,下面的代码演示了如何使用注解实现AOP: ```java @Aspect @Component public class LogAspect { @Pointcut("execution(* com.example.demo.service.*.*(..))") public void pointcut() {} @Before("pointcut()") public void before(JoinPoint joinPoint) { System.out.println("before " + joinPoint.getSignature().getName()); } @After("pointcut()") public void after(JoinPoint joinPoint) { System.out.println("after " + joinPoint.getSignature().getName()); } @Around("pointcut()") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("around before " + joinPoint.getSignature().getName()); Object result = joinPoint.proceed(); System.out.println("around after " + joinPoint.getSignature().getName()); return result; } } ``` 在上面的代码中,@Aspect注解表示这是一个切面类,@Component注解表示这是一个Spring组件。@Pointcut注解定义了切点,这里表示拦截com.example.demo.service包下的所有方法。@Before、@After、@Around注解分别表示前置通知、后置通知、环绕通知,它们的参数是切点表达式。 通过这种方式,我们可以很方便地实现AOP,将横切关注点从业务逻辑中分离出来,提高代码的可维护性和可重用性。 ### 回答2: Spring Boot是一种核心框架Spring的扩展,其自动化配置和默认设置能够降低Spring应用程序的开发难度和复杂性。AOP(面向切面编程)是Spring框架中非常重要的一个特性,它提供了一种方法用于跨越应用程序多个部分进行交叉剖面的分离关注点。Spring Boot使用注解实现AOP,使得切面编程的应用变得更加简单和易于维护。 Spring Boot使用AspectJ注解为Aspect提供了支持。Aspect指定义切面的类,通过使用@Aspect注释标记Aspect。在Aspect中,开发者可以通过使用其他注释来定义切点和通知,以及为方便切面声明添加其他接口方法。 切点是一个表达式,它指定要应用切面的位置,例如在方法前,方法后,异常抛出,或联接点(连接点)。在Spring Boot中,可以使用@Pointcut注释来定义切点表达式。可以将切点表达式定义为公共的或私有的类方法,以便重复使用。 通知是切面类中的方法,它定义了在切点执行时应该执行的行为。Spring Boot支持五种类型的通知注释: - @Before:在方法执行前执行切面代码。 - @AfterReturning:当方法正常返回值后执行切面代码。 - @AfterThrowing:在方法抛出异常后执行切面代码。 - @After:在方法执行后执行切面代码,无论方法执行结果如何。 - @Around:在方法执行前和执行后执行切面代码。 在编写完AOP切面以后,还需要将其纳入到Spring IoC容器中。使用@Component注释将切面类注册为Spring Bean组件,并在应用程序上下文中启用AspectJ自动代理。 总之,使用注释实现AOPSpring Boot中非常重要和受欢迎的特征之一。将重复的代码分离到切面中,确保与业务逻辑分离的代码清晰,可读性和可维护性都得到了极大的提高。 ### 回答3: Spring Boot是一个快速开发的框架,使用起来非常简便,其中注解AOP也是Spring Boot框架中非常常用的一种方式,本文主要介绍Spring Boot如何使用注解实现AOP注解AOPSpring框架提供的一种AOP编程的方式,它可以通过添加@Aspect注解来定义切面,通过添加@Before、@After、@Around等注解来定义具体的增强逻辑。Spring Boot实现AOP时,需要借助于AspectJ框架,同时需要定义切面和切点。 首先,需要在应用程序中添加“spring-boot-starter-aop”依赖,然后定义一个被增强的Bean,并在其上添加需要增强的方法(也可以在类或者方法上添加@Aspect注解)。 然后,需要定义一个切面,并在切面上添加@Before、@After、@Around等注解来定义增强逻辑,通过AspectJ的注解方式,可以实现对方法的调用进行切面操作。 最后,需要通过在启动类中添加@EnableAspectJAutoProxy注解来启用AOP代理自动创建功能。 总而言之,Spring Boot中使用注解实现AOP非常简单,只需要添加依赖,定义切面,定义增强逻辑,最后在启动类中启用AOP代理自动创建功能即可。注解AOP可以使得编程更加简单和便捷,同时也能够提高代码的可读性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值