SpringBoot 加载系统资源至缓存

文章介绍了如何在SpringBoot项目中,使用CommandLineRunner接口在启动时加载数据字典到缓存,以提高后续业务调用的效率。通过实现CommandLineRunner的run方法,配合缓存类DictResourceCache和工具类SpringUtils,实现了启动时加载用户信息到缓存,并在Controller中直接获取。PostMan测试验证了该功能的正确性。
摘要由CSDN通过智能技术生成

开发环境: IDEA 2022.1.4+ MyBatis

        代码参考:springboot启动后加载字典表数据供业务调用

        参考

        Spring-boot中的CommandLineRunner的作用 - 简书

        https://www.cnblogs.com/yanxiaoguo/p/16167221.html

目录

1. 概述

2. 实现步骤

        2.1 新建一个缓存类 DictResourceCache

        2.2 新建Runner类实现CommandLineRunner接口

        2.3 定义工具类 SpringUtils

        2.4 controller接口

        2.5 PostMan测试

3. 结语


1. 概述

        平常做PC端程序时候,在程序启动时候,都会去事先加载数据字典信息,想着SpringBoot也可以实现这块功能,特百度查询资料,可以使用CommandLineRunner来实现。

        通过实现CommandLineRunner接口的run方法, 结合@Component、@Order的使用,可以来实现数据加载顺序。对于@Order的value属性(int类型),值越低优先级越高。
       

2. 实现步骤

        效果: 我在服务启动时候,将用户信息加载到缓存中,当使用PostMan来调用获取用户信息时候,从缓存中直接获取.

        此处SpringBoot+MyBatis的配置就暂不描述了。

        2.1 新建一个缓存类 DictResourceCache

        这个类主要有个静态的集合对象cache,

        Map<String,List<?>>, key值代表字典名称,List<?>为对应的集合。也就是说,这个Map对象可以缓存多个数据字典的信息。 然后可以根据getDict()方法, 获取特定数据字典信息。

@Slf4j
public class DictResourceCache {
    private static UserMapper userMapper;

    private static Map<String, List<?>> cache= new HashMap<>();

    /**
     * 加载字典
     */
    public static void load(){
        cache.clear();
        SqlSession sqlSession= null;
        try{
            sqlSession= MybatisUtils.getSqlSession();
            //userMapper= sqlSession.getMapper(UserMapper.class);
            userMapper= SpringUtils.getBean(UserMapper.class);
            List<User> listUser= userMapper.getUserList();
            cache.put("User", listUser);
        } catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 根据字典名 获取元素列表
     * @param dicName
     * @return
     */
    public static List<?> getDict(String dicName){
        List<?> list= cache.get(dicName);
        if (CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        return cache.get(dicName);
    }
}

        2.2 新建Runner类实现CommandLineRunner接口

        这个接口使用了@Component、@Order注解。 重写run()方法,调用缓存类的DictResourceCache的load()方法。

@Slf4j
@Component
@Order(2)
public class DictResourceRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        log.info("加载数据字典...");
        DictResourceCache.load();
        log.info("加载完毕...");
    }
}

        2.3 定义工具类 SpringUtils

        这个我看的半明白, 与BeanFactory有关。通过@Component注解,将该类交由Spring管理.

@Component
public class SpringUtils implements BeanFactoryPostProcessor {
    /**
     * Spring应用上下文环境
     */
    private static ConfigurableListableBeanFactory beanFactory;


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        SpringUtils.beanFactory= configurableListableBeanFactory;
    }

    public static <T> T getBean(String name) throws BeansException{
        name= lowerCaseInit(name);
        if(containsBean(name)){
            return (T) beanFactory.getBean(name);
        } else{
            return null;
        }
    }

    /**
     * 获取
     * @param cls
     * @return
     * @param <T>
     * @throws BeansException
     */
    public static <T> T getBean(Class<T> cls) throws BeansException{
        T result= (T) beanFactory.getBean(cls);
        return result;
    }

    /**
     * 判断 BeanFactory是否包含bean对象
     * @param name
     * @return
     */
    public static boolean containsBean(String name){
        return beanFactory.containsBean(name);
    }

    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
     * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     * @param name
     * @return
     * @throws NoSuchBeanDefinitionException
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException{
        return beanFactory.isSingleton(name);
    }

    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException{
        return beanFactory.getType(name);
    }

    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException{
        return beanFactory.getAliases(name);
    }

    /**
     * 首字母小写
     * @param name
     * @return
     */
    private static String lowerCaseInit(String name){
        if(name.length()>0){
            char c= name.charAt(0);
            if(c>=65 && c<=90){
                int i= c+ 32;
                return ((char)i)+ name.substring(1);
            } else{
                return name;
            }
        } else{
            return null;
        }
    }
}

        2.4 controller接口

        在接口处理中,直接从缓存集合中获取User的所有字典信息。

    @GetMapping("/user/getUserList")
    public Result<?> getUserList(){
        return Result.ok(DictResourceCache.getDict("User"));
//        System.out.println("info:>>>>>>>>>>>>>>>"+ info);
//        List<User> userList= service.query();
//        return Result.ok(userList);
    }

        2.5 PostMan测试

3. 结语

        我简单理解为, @Component+@Order组合,Spring启动会自动去加载对应的类(实现CommandLineRunner接口),并执行run()方法。

        SpringUtils看的半明白,我得多理解下。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值