Springboot 项目启动时扫描所有枚举并存入缓存(redis)

  • 为什么这么做? 为了springboot 注解属性转换字典方便一点(使用缓存的方式在Springboot 启动时获取字典数据)

  • 在启动时会扫描com.vehicle.manager.core.enumerate包下的所有枚举(包括类中的内部枚举),并取出对应属性以json的方式存入redis

  • 目录结构如下:

image.png

  • RedisUtil可以在RedisUtil获取
  • Springboot 项目启动时的处理都可以参考这个方式
package com.vehicle.manager.core.enumerate;

import com.alibaba.fastjson.JSON;
import com.vehicle.manager.core.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author zr 2024/3/15
 */
@Component
@Order(1) // 确保在其他 Bean 初始化之前执行
@Slf4j
public class EnumScanner implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private ApplicationContext applicationContext;

    private StringRedisTemplate redisTemplate;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext().equals(applicationContext)) {
            this.redisTemplate = applicationContext.getBean(StringRedisTemplate.class);
            scanEnums();
        }
    }

    public void scanEnums() {
//        String dicDataStr = RedisUtil.StringOps.get("dicData");
//        if (ObjectUtils.isNotEmpty(dicDataStr)){
//            return;
//        }
        String packageName = "com.vehicle.manager.core.enumerate"; // 替换成你要扫描的包路径
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        scanner.addIncludeFilter(new AssignableTypeFilter(Enum.class));

        Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(packageName);
        HashMap<String, Map<String, String>> dicData = new HashMap<>();
        for (BeanDefinition candidateComponent : candidateComponents) {
            String className = candidateComponent.getBeanClassName();
            // 这里可以对枚举类进行处理,比如输出类名或者其他操作
//            log.info("Found enum class: " + className);

            Class<?> enumClass = null;
            try {
                enumClass = Class.forName(className);
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }

            if (enumClass.isEnum()) {
                Map<String,String> dic = new LinkedHashMap();
                Object[] enumConstants = enumClass.getEnumConstants();
                for (Object enumConstant : enumConstants) {
//                    log.info("enumConstant",enumConstant);
                    dic.put(enumConstant.toString(),getDesc(enumConstant));
                }
                String simpleName = enumClass.getSimpleName();
                String key = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);

                dicData.put(key,dic);

            }
//            dicData.put(key, JSON.toJSONString());

        }
        RedisUtil.StringOps.set("dicData", JSON.toJSONString(dicData));

    }

    private static  String  getDesc(Object enumConstant) {
        try {
            Field descField = enumConstant.getClass().getDeclaredField("desc");
            descField.setAccessible(true);
            String methodName = "get" + descField.getName().substring(0, 1).toUpperCase() + descField.getName().substring(1);
            Method getDescMethod = enumConstant.getClass().getMethod(methodName);
            return (String) getDescMethod.invoke(enumConstant);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

存入redis中的数据结构如下:

  • json中的key为枚举的名称首字母小写
  • 当然用redis的hash结构存储更好,当时开发时没有考虑到,有需要的可以自己改造

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/748645.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无线领夹麦克风怎么挑选,能让声音变好听的领夹麦推荐大全

近年来&#xff0c;随着直播销售和个人视频日志&#xff08;Vlog&#xff09;的流行&#xff0c;自媒体内容创作已经成为一种文化现象。这一现象不仅改变了人们获取信息的方式&#xff0c;也极大地推动了相关音频设备的发展。无线领夹麦克风&#xff0c;以其轻巧的设计和出色的…

GPT-5即将登场,AI赋能未来:我们该如何迎接这场技术变革?

文章目录 从高中生到博士生&#xff1a;GPT-4到GPT-5的飞跃科技界的惊叹与期待GPT-5的影响与应用场景1. 更强的自然语言处理能力2. 智能助理的升级3. 教育与培训4. 创意产业5. 数据分析与决策支持 如何迎接GPT-5的到来&#xff1f;1. 学习与适应2. 探索与创新3. 合作与共赢4. 关…

gin-vue -admin 初始化安装后 进入 后台首页报错

报错原因&#xff1a; 因为 我是使用的phpstudy 小皮的数据库 默认的是MySam 的引擎 mysql 引擎需要是 innoDB 解决办法 &#xff1a; 在linux 的环境下 配置一个数据库 &#xff0c; 我是用的是vmware 虚拟机

windows系统如何快速查看显卡详情信息

winR&#xff0c;输入dxdiag 打开DirectX诊断工具&#xff0c;可以看到显卡的详细硬件信息

帝国cms未审核文章可视化预览效果

有时候为了让编辑更加清楚的看到别人审核之后的效果&#xff0c;同时文章有需要下一级审核才能在前端展示出来&#xff0c;今天就来展示一个未审核文章预览审核后的效果 这次给某出版社开发的时候&#xff0c;他们需要实现编辑能够预览自己发布之后的审核效果&#xff0c;所以就…

深度學習筆記14-CIFAR10彩色圖片識別(Pytorch)

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習紀錄博客&#x1f356; 原作者&#xff1a;K同学啊 | 接輔導、項目定制 一、我的環境 電腦系統&#xff1a;Windows 10 顯卡&#xff1a;NVIDIA GeForce GTX 1060 6GB 語言環境&#xff1a;Python 3.7.0 開發…

一本顶三本?入门LLM大模型必读《大模型应用开发极简入门》附PDF书籍

今天带来的是最近刚出版的新书&#xff1a; 《大模型应用开发极简入门&#xff1a;基于 GPT-4 和ChatGPT》 。 这本书是 O’Reilly 出版的&#xff0c;两位共同作者是来自 Worldline 公司的机器学习研究员 Olivier Caelen 和 数据工程师 Marie-Alice Blete。这两位作者一位侧重…

Zynq7000系列FPGA中的定时器详细介绍

每个Cortex-A9处理器都有自己的专用32位定时器和32位看门狗定时器。两个处理器共享一个全局64位定时器。这些定时器总是以CPU频率&#xff08;CPU_3x2x&#xff09;的1/2进行计时。 在系统级&#xff0c;有一个24位看门狗定时器和两个16位三重定时器/计数器。 系统看门狗定时器…

域名 Whois 检测:企业网络安全与品牌保护的利器

域名是企业在互联网上的重要标识&#xff0c;其安全性和合规性直接影响着企业的业务运营和品牌声誉。而域名 Whois 检测通过全面分析和监控域名的 Whois 信息&#xff0c;为企业提供了多方面的保障&#xff0c;帮助企业识别潜在的网络威胁、保护品牌资产、优化域名管理。 那么什…

向量数据库原理之向量索引

向量索引 在前面的文章中讲解了milvus的源码安装——向量数据库milvus源码剖析之开篇&#xff0c;向量数据库通常具备以下特点&#xff1a; 向量索引&#xff1a;用来支持高效的搜索&#xff0c;快速定位与查询向量相关的数据集。相似度搜索&#xff1a;支持余弦、欧式距离等的…

MySQL数据库基础练习系列:科研项目管理系统

DDL CREATE TABLE Users (user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT 用户ID,username VARCHAR(50) NOT NULL UNIQUE COMMENT 用户名,password VARCHAR(255) NOT NULL COMMENT 密码,gender ENUM(男, 女) NOT NULL COMMENT 性别,email VARCHAR(100) UNIQUE COMMENT 邮箱 …

@PathVariable注解的使用及源码解析

前言 PathVariable 注解是我们进行JavaEE开发&#xff0c;最常见的几个注解之一&#xff0c;这篇博文我们以案例和源码相结合&#xff0c;帮助大家更好的了解PathVariable 注解 使用案例 1.获取 URL 上的值 RequestMapping("/id/{id}") public Object getId(Path…

Kubernetes Artemis系列 | 使用 ArtemisCloud Operator 部署 artemis

目录 一、ArtemisCloud Operator 介绍二、部署ArtemisCloud Operator三、使用 ArtemisCloud Operator 部署 artemis四、管理队列五、缩减规模时消息迁移 一、ArtemisCloud Operator 介绍 ArtemisCloud Operator 是一个用于管理和部署云端基础设施的工具。它基于 Kubernetes 平…

精益软件开发:从理念到实践

目录 前言1. 精益软件开发的起源与背景1.1 精益制造的起源1.2 精益思想在软件开发中的应用 2. 精益软件开发的核心原则2.1 消除浪费2.2 强调学习和持续改进2.3 快速交付2.4 尊重团队成员 3. 实施精益软件开发的方法3.1 精简流程3.2 持续反馈和迭代3.3 持续集成和持续交付3.4 建…

Vue 学习之 axios

目录 执行安装命令&#xff1a;npm install axios 使用的时候导入 axios以data&#xff0c;params&#xff0c;headers传参方式的区别 axios封装 是一个基于 promise 的 网络请求库&#xff0c;作用于浏览器和 node.js 中。使用Axios可以在前端项目中发送各种方式的HTTP请求…

chromium源码魔改思路

1.首先确定需要要改动的JS的API 比如要改动navigator.webdriver false 2.在官网查找JS的API https://developer.mozilla.org/zh-CN/docs/Web/Guide 3.在chromium源码官网查找源码 https://source.chromium.org/chromium/chromium/src 直接修改webdriver()返回值即可 4.然后…

idea常用配置 | 快捷注释

idea快速注释 一、类上快速注释 &#xff08;本方法是IDEA环境自带的&#xff0c;设置特别方便简单易使用&#xff09; 1、偏好设置->编辑器->文件和代码模版 | File-Settings-Editor-File and Code Templates 2、右下方的“描述”中有相对应的自动注注释配置格式 贴…

Actor-agnostic Multi-label Action Recognition with Multi-modal Query

标题&#xff1a;基于多模态查询的非特定行为者多标签动作识别 源文链接&#xff1a;https://openaccess.thecvf.com/content/ICCV2023W/NIVT/papers/Mondal_Actor-Agnostic_Multi-Label_Action_Recognition_with_Multi-Modal_Query_ICCVW_2023_paper.pdfhttps://openaccess.t…

Java研学-Shiro安全框架(二)

四 Shiro 鉴权 1 介绍 授权功能&#xff1a;就是为用户分配相关的权限的过程&#xff1b;鉴权功能&#xff1a;判断当前访问用户是否有某个资源的访问权限的过程。我们的权限管理系统是基于角色的权限管理&#xff0c;所以在系统中应该需要下面三个子模块&#xff1a;用户管理…

Theta方法:一种时间序列分解与预测的简化方法

Theta方法整合了两个基本概念:分解时间序列和利用基本预测技术来估计未来的价值。 每个数据科学爱好者都知道&#xff0c;时间序列是按一定时间间隔收集或记录的一系列数据点。例如&#xff0c;每日温度或经济指标的月值。把时间序列想象成不同成分的组合&#xff0c;趋势(数据…