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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot项目启动时写入Redis,可以使用Spring Boot的启动事件来实现。下面是一个示例代码: 首先,创建一个监听器类,实现`ApplicationListener`接口,监听`ApplicationReadyEvent`事件,在项目启动完成后执行相应的操作: ```java import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; @Component public class RedisInitializer implements ApplicationListener<ApplicationReadyEvent> { private final RedisTemplate<String, String> redisTemplate; public RedisInitializer(RedisTemplate<String, String> redisTemplate) { this.redisTemplate = redisTemplate; } @Override public void onApplicationEvent(ApplicationReadyEvent event) { // 在这里进行Redis的写入操作 redisTemplate.opsForValue().set("key", "value"); } } ``` 在上面的代码中,我们使用了`RedisTemplate`来进行Redis的操作。你可以根据实际需求修改`set`方法的参数来写入不同的数据。 然后,确保你已经正确配置了Redis相关的依赖和连接信息。在`application.properties`(或`application.yml`)文件中,添加Redis的连接配置信息,例如: ```properties spring.redis.host=localhost spring.redis.port=6379 ``` 最后,在你的Spring Boot项目中添加上述的监听器类,它会在项目启动完成后自动执行Redis写入操作。 这样,每次启动Spring Boot项目时,都会将数据写入Redis中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值