2021SC@SDUSC
目录
一、MenuItem
1.MenuItem
MenuItem为JPress的菜单项类,是JPress 的一个module。其包含了菜单项的基本属性。
private String id; private String text; private String icon; private String groupId; private String url; private int order = 100; private String target;
其构造函数中实现了用户菜单项构造和管理员菜单项构造。MenuItem还重写了equals方法,虽然不难,但是可供积累:
@Override public boolean equals(Object obj) { if (obj == null || obj instanceof MenuItem == false) { return false; } return ((MenuItem) obj).getId().equals(id); }
MenuItem的equals()先实判断obj是否和MenuItem同一类或者是否是空值,然后再通过MenuItem的id来比较,若它们的id相同,则说明它们相同。
2.MenuGroup
MenuGroup是JPress的菜单组项,包含了菜单组项的基本属性。
private int order = 100; private String text; private String icon; private String id; private List<MenuItem> items;
可以通过private List<MenuItem> items,很容易看出JPress的带单是二级菜单结构,而不是多级菜单结构。
其items属性不是静态的,那么在初始化类的时候不会初始化items属性。其items属性的创建模式是懒汉式的单例模式。
public void addItem(MenuItem item) { if (items == null) { items = new ArrayList<>(); } if (items.contains(item)) { return; } items.add(item); items.sort(Comparator.comparingInt(MenuItem::getOrder)); }
可以看到,只有在需要添加MenuItem的时候,才会初始化items属性。这样的好处是延迟创建new ArrayList<>()对象,节约资源。但是这样有一个缺点。没有考虑线程安全问题,它是线程不安全的,多个线程处理时可能不能获得同一个实例items。但是考虑到添加MenuItem的操作不是频繁的,且难以出现多线程添加MenuItem的场景,所以这样的缺点可以忽略。
二、MenuManager
1.MenuArrayList
MenuArrayList是JPress中专门用于存储管理菜单组的List,其继承了ArrayList,重写了add方法,实现了sort方法。其add方法中,若
@Override public boolean add(MenuGroup menuGroup) { if (contains(menuGroup)) { throw new RuntimeException("menuGroup:" + menuGroup + " has exits."); } return sort(super.add(menuGroup)); } private boolean sort(boolean success){ if (success) { sort(Comparator.comparingInt(MenuGroup::getOrder)); } return success; }
当遇到一些比较重要的类时,可以考虑写一个专门的List来管理该类。
2.MenuManager
MenuManager是JPress管理菜单组的类,其继承了JbootEventListener,会在JPress项目运行的时候启动。其所有属性都使用了懒汉式的构建方式。类加载时就在静态区创建了MenuManager实例。
同时,该类被创建时,就自带了系统菜单列表,模板菜单列表,用户财务菜单等私有属性。在类初始化阶段就会初始化后台的固定菜单、初始化后台的 module菜单、初始化用户中心菜单。
假设要初始化系统菜单组,具体的初始化方式如下:
if (JPressMenuConfig.me.isWechatEnable()) { MenuGroup wechatMenuGroup = new MenuGroup(); wechatMenuGroup.setId(JPressConsts.SYSTEM_MENU_WECHAT_PUBULIC_ACCOUNT); wechatMenuGroup.setText("微信"); wechatMenuGroup.setIcon("<i class=\"fab fa-weixin\"></i>"); systemMenus.add(wechatMenuGroup); }
可以看到,系统会先判断菜单配置,查看微信菜单项是否可用,然后会实例化一个菜单组。菜单组的ID为一个字符串常量,用JPressConsts类保存。setIcon设置了h5的代码。最后把这个菜单组放到systemMenus列表中存储。