栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

APIJSON(十一:AbstractVerifier源码阅读(2))

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

APIJSON(十一:AbstractVerifier源码阅读(2))

APIJSON(十一:AbstractVerifier源码阅读(2))

2021SC@SDUSC

文章目录
  • APIJSON(十一:AbstractVerifier源码阅读(2))
    • 元素定义
      • map
      • static{}
        • 概念解释
        • linkedHashMap
        • List
    • 实现的方法
      • getAccessMap
        • java 中@interface 和interface 的区别

元素定义

类的一开始,当然还是一大堆的元素定义——

// 共享 STRUCTURE_MAP 则不能 remove 等做任何变更,否则在并发情况下可能会出错,加锁效率又低,所以这里改为忽略对应的 key
public static final Map> ROLE_MAP;

public static final List OPERATION_KEY_LIST;

// >
// >
@NotNull
public static final Map> SYSTEM_ACCESS_MAP;
@NotNull
public static final Map> ACCESS_MAP;

// >
// >
@NotNull
public static final Map> REQUEST_MAP;

// 正则匹配的别名快捷方式,例如用 "PHONE" 代替 "^((13[0-9])|(15[^4,\D])|(18[0-2,5-9])|(17[0-9]))\d{8}$"
@NotNull
public static final Map COMPILE_MAP;
map

这里大量使用了@NotNull的注解,申明其不能为空,以及map接口

Map是java中的接口,Map.Entry是Map的一个内部接口。

Map提供了一些常用方法,如keySet()、entrySet()等方法。

keySet()方法返回值是Map中key值的集合;entrySet()的返回值也是返回一个Set集合,此集合的类型为Map.Entry。

Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry。它表示Map中的一个实体(一个key-value对)。接口中有getKey(),getValue方法。

接下来则是一个static块

static {
   ROLE_MAP = new linkedHashMap<>();
   ROLE_MAP.put(UNKNOWN, new Entry());
   ROLE_MAP.put(LOGIN, new Entry("userId>", 0));
   ROLE_MAP.put(CONTACT, new Entry("userId{}", "contactIdList"));
   ROLE_MAP.put(CIRCLE, new Entry("userId-()", "verifyCircle()")); // "userId{}", "circleIdList"));  // 还是 {"userId":"currentUserId", "userId{}": "contactIdList", "@combine": "userId,userId{}" } ? 
   ROLE_MAP.put(OWNER, new Entry("userId", "userId"));
   ROLE_MAP.put(ADMIN, new Entry("userId-()", "verifyAdmin()"));
   
   OPERATION_KEY_LIST = new ArrayList<>();
   OPERATION_KEY_LIST.add(TYPE.name());
   OPERATION_KEY_LIST.add(VERIFY.name());
   OPERATION_KEY_LIST.add(INSERT.name());
   OPERATION_KEY_LIST.add(UPDATE.name());
   OPERATION_KEY_LIST.add(REPLACE.name());
   OPERATION_KEY_LIST.add(EXIST.name());
   OPERATION_KEY_LIST.add(UNIQUE.name());
   OPERATION_KEY_LIST.add(REMOVE.name());
   OPERATION_KEY_LIST.add(MUST.name());
   OPERATION_KEY_LIST.add(REFUSE.name());


   SYSTEM_ACCESS_MAP = new HashMap>();

   SYSTEM_ACCESS_MAP.put(Access.class.getSimpleName(), getAccessMap(Access.class.getAnnotation(MethodAccess.class)));
   SYSTEM_ACCESS_MAP.put(Function.class.getSimpleName(), getAccessMap(Function.class.getAnnotation(MethodAccess.class)));
   SYSTEM_ACCESS_MAP.put(Request.class.getSimpleName(), getAccessMap(Request.class.getAnnotation(MethodAccess.class)));
   SYSTEM_ACCESS_MAP.put(Response.class.getSimpleName(), getAccessMap(Response.class.getAnnotation(MethodAccess.class)));

   if (Log.DEBUG) {
      SYSTEM_ACCESS_MAP.put(Table.class.getSimpleName(), getAccessMap(Table.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(Column.class.getSimpleName(), getAccessMap(Column.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(PgAttribute.class.getSimpleName(), getAccessMap(PgAttribute.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(PgClass.class.getSimpleName(), getAccessMap(PgClass.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(SysTable.class.getSimpleName(), getAccessMap(SysTable.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(SysColumn.class.getSimpleName(), getAccessMap(SysColumn.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(ExtendedProperty.class.getSimpleName(), getAccessMap(ExtendedProperty.class.getAnnotation(MethodAccess.class)));

      SYSTEM_ACCESS_MAP.put(document.class.getSimpleName(), getAccessMap(document.class.getAnnotation(MethodAccess.class)));
      SYSTEM_ACCESS_MAP.put(TestRecord.class.getSimpleName(), getAccessMap(TestRecord.class.getAnnotation(MethodAccess.class)));
   }

   ACCESS_MAP = new HashMap<>(SYSTEM_ACCESS_MAP);

   REQUEST_MAP = new HashMap<>(ACCESS_MAP.size()*6);  // 单个与批量增删改

   COMPILE_MAP = new HashMap();
}
static{} 概念解释

1、 类加载的特性
在JVM的生命周期里,每个类只会被加载一次。

类加载的原则:延迟加载,能少加载就少加载,因为虚拟机的空间是有限的。

2、 类加载的时机
1)第一次创建对象要加载类.

2)调用静态方法时要加载类,访问静态属性时会加载类。

3)加载子类时必定会先加载父类。

4)创建对象引用不加载类.

  1. 子类调用父类的静态方法时

​ (1)当子类没有覆盖父类的静态方法时,只加载父类,不加载子类

​ (2)当子类有覆盖父类的静态方法时,既加载父类,又加载子类

6)访问静态常量,如果编译器可以计算出常量的值,则不会加载类,例如:public static final int a =123;否则会加载类,例如:public static final int a = math.PI。

静态块(static{})
(1) static关键字还有一个比较关键的作用,用来形成静态代码块(static{}(即static块))以优化程序性能。

(2) static块可以置于类中的任何地方,类中可以有多个static块。

(3) 在类初次被加载的时候执行且仅会被执行一次(这是优化性能的原因!!!),会按照static块的顺序来执行每个static块,一般用来初始化静态变量和调用静态方法。
否则每当调用方法时,都会生成这些成员对象,造成空间的浪费。

linkedHashMap
ROLE_MAP = new linkedHashMap<>();

首先可以看到先创建了一个linkedHashMap的对象

本质上,linkedHashMap = HashMap + 双向链表,也就是说,HashMap和双向链表合二为一即是linkedHashMap。也可以这样理解,linkedHashMap 在不对HashMap做任何改变的基础上,给HashMap的任意两个节点间加了两条连线(before指针和after指针),使这些节点形成一个双向链表。在linkedHashMapMap中,所有put进来的Entry都保存在HashMap中,但由于它又额外定义了一个以head为头结点的空的双向链表,因此对于每次put进来Entry还会将其插入到双向链表的尾部。

而其中大量使用的put方法就是给linkedHashMap添加键值对的方法。具体可参考如下文章:

Map 综述(一):彻头彻尾理解 HashMap

Map 综述(二):彻头彻尾理解 linkedHashMap

List
public static final List OPERATION_KEY_LIST;

List 是一个接口,它继承于Collection的接口。它代表着有序的队列。

List中元素可以重复,并且是有序的(这里的有序指的是按照放入的顺序进行存储。如按照顺序把1,2,3存入List,那么,从List中遍历出来的顺序也是1,2,3)。

void add(int index, E element)

在指定位置插入元素,后面的元素都往后移一个元素。

实现的方法 getAccessMap
public static HashMap getAccessMap(MethodAccess access)

注意到getAccessMap传入的值是MethodAccess类

public @interface MethodAccess

这就是MethodAccess的类的定义,发现用了看起来很奇怪的@interface

java 中@interface 和interface 的区别

什么是java Annotation
Java 从1.5开始提供了 Annotation (注释,标注),它用来修饰应用程序的元素(类,方法,属性,参数,本地变量,包、元数据),编译器将其与元数据一同存储在 class 文件中,运行期间通过 Java 的反射来处理对其修饰元素的访问。Annotation 仅仅用来修饰元素,而不能影响代码的执行。只有通过其配套的框架或工具才能对其信息进行访问和处理。

区别

①、interface :声明了这是一个java 的接口

②、@interface : 是用来修饰 Annotation 的,请注意,它不是 interface。这个关键字声明隐含了一个信息:它是继承了 java.lang.annotation.Annotation 接口,而不是声明了一个 interface。

这其中主要对请求方法的权限做了定义,只允许某些角色通过对应方法访问数据库。

比如说get方法,默认允许的角色UNKNOWN, LOGIN, CONTACT, CIRCLE, OWNER, ADMIN;

String[] GET() default {UNKNOWN, LOGIN, CONTACT, CIRCLE, OWNER, ADMIN};

可以发现这些方法的权限是从低到高的,POST、PUT、DELETE方法只默认允许OWNER,或ADMIN进行使用

String[] GET() default {UNKNOWN, LOGIN, CONTACT, CIRCLE, OWNER, ADMIN};

String[] HEAD() default {UNKNOWN, LOGIN, CONTACT, CIRCLE, OWNER, ADMIN};

String[] GETS() default {LOGIN, CONTACT, CIRCLE, OWNER, ADMIN};

String[] HEADS() default {LOGIN, CONTACT, CIRCLE, OWNER, ADMIN};

String[] POST() default {OWNER, ADMIN};

String[] PUT() default {OWNER, ADMIN};

String[] DELETE() default {OWNER, ADMIN};

重新到我们的getAcessMap方法,它就是用来获取这些权限Map的。

if (access == null) {
   return null;
}

HashMap map = new HashMap<>();
map.put(GET, access.GET());
map.put(HEAD, access.HEAD());
map.put(GETS, access.GETS());
map.put(HEADS, access.HEADS());
map.put(POST, access.POST());
map.put(PUT, access.PUT());
map.put(DELETE, access.DELETE());
return map;

put(GET, access.GET());
map.put(HEAD, access.HEAD());
map.put(GETS, access.GETS());
map.put(HEADS, access.HEADS());
map.put(POST, access.POST());
map.put(PUT, access.PUT());
map.put(DELETE, access.DELETE());
return map;

它首先进行判断access是否为空,不是的话,就会创建一个HashMap对这些权限进行依次存储,并返回这个HashMap。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/659417.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号