注解是 jdk 5.0 引入的一种注释机制。注解可以作用在类型(类、接口、枚举等)、属性、方法、参数等不同位置,具体的 jdk 版本所支持的注解位置可参考 java.lang.annotation.elementtype 。此外还有注解的策略,也就是 retentionpolicy ,这里不加赘述。

注解可以实现很多功能,其中最主要的就是进行代码标注,所以有时候注解也叫做标注。使用起来也基本顾名思义,就是对代码进行标注,简化部分代码的逻辑。

下面我们就着手实现一个简单的权限控制注解,来对注解有一个基本的了解。

准备

@permission 注解

注解本身的代码很简单。下面实现的是一个 @permission 注解,为了方便使用,这里只提供一个属性value,因为如果一个注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略掉“value=”部分。

import java.lang.annotation.*;

@target({elementtype.parameter}) // 注解可用于参数
@retention(retentionpolicy.runtime) // 注解在运行时可由jvm读入
@documented
public @interface permission {
  string value() default "";
}

user 类

一个简单的user类,包含 permissions 用于保存用户的权限。

import lombok.data;

@data
public class user {
  private string id;
  private string name;

  private set<string> permissions;
}

userservice 类

简单的 service 类,用于判断权限。

@service
public class userservice {
  public boolean checkcreatepermission(@permission("创建用户") user user) {
    return true;
  }

  public boolean checkdeletepermission(@permission("删除用户") user user) {
    return true;
  }
}

permissionaspect 类

利用 springboot 简单地设置切面,获取注解并使用。这里直接

@aspect
@component
public class permissionaspect {
  // 需要修改为实际的 service 所在的 package
  @pointcut("execution(public * tk.yubarimelon.mongodemo.service.*.*(..))") 
  public void permissioncheck() {
  }

  @around("permissioncheck()")
  public object before(proceedingjoinpoint joinpoint) throws throwable {
    object[] params = joinpoint.getargs();
    // 获取方法,此处可将signature强转为methodsignature
    methodsignature signature = (methodsignature) joinpoint.getsignature();
    method method = signature.getmethod();

    // 获取参数注解,1维是参数,2维是注解
    annotation[][] parameterannotations = method.getparameterannotations();
    for (int i = 0; i < parameterannotations.length; i++) {
      object param = params[i];
      annotation[] annotations = parameterannotations[i];
      if (!(param instanceof user) || annotations.length == 0) {
        continue;
      }
      for (annotation annotation : annotations) {
        if (annotation.annotationtype().equals(permission.class)) {
          permission permission = (permission) annotation;
          user user = (user) param;
          if (collectionutils.isempty(user.getpermissions())) {
            log.error(user.getname() + " 无任何权限!");
            return false;
          }
          if (!stringutils.haslength(permission.value())) {
            log.error(joinpoint.getsignature().tostring() + "权限设置异常");
            return false;
          }
          if (!user.getpermissions().contains(permission.value())) {
            log.error(joinpoint.getsignature().tostring() +": "+user.getname() + " 无权限: " + permission.value());
            return false;
          }
          return joinpoint.proceed();
        }
      }
    }
    return joinpoint.proceed();
  }
}

applicationtests 类

简单的测试类,用于测试代码。这里简单的配置一个用户只有创建用户的权限

@springboottest
class applicationtests {

  @autowired
  userservice userservice;

  @test
  void contextloads() {
  }

  @test
  void checkuser() {
    user user = new user();
    user.setname("小明");
    set<string> permissions = new hashset<>();
    permissions.add("创建用户");
    user.setpermissions(permissions);

    system.out.println("checkcreatepermission " + userservice.checkcreatepermission(user));
    system.out.println("checkdeletepermission " + userservice.checkdeletepermission(user));
  }
}

输出如下日志,证明权限设置起作用了。

checkcreatepermission true
2021-01-31 11:44:45.895 error 12388 — [           main] t.y.mongodemo.aop.permissionaspect       : boolean tk.yubarimelon.mongodemo.service.userservice.checkdeletepermission(user): 小明 无权限: 删除用户
checkdeletepermission false

到此这篇关于浅谈基于springboot实现一个简单的权限控制注解的文章就介绍到这了,更多相关springboot 权限控制注解内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!