【JAVA】一个项目如何预先加载数据?

news2024/11/16 19:50:41

这里写目录标题

    • 需求
    • 实现
      • @Autowired
      • @PostConstruct
        • 实例
      • CommandLineRunner
        • 实例
      • ApplicationListener
        • 实例
      • 参考

需求

一般我们可能会有一些在应用启动时加载资源的需求,局部或者全局使用,让我们来看看都有哪些方式实现。

实现

@Autowired

如果是某个类里需求某个父类的所有子类,不论是接口还是抽象类,其实都可以使用@Autowired的批量注入,非常方便。

//此处假设我们的Animal是个接口,有5个不同的实现类,可以使用以下方式批量注入使用。

    @Autowired
    private List<Animal> animalList;
    
    
    @Autowired
    private Map<String,Animal> animalMap;

@PostConstruct

PostConstruct是java提供的注解,可以在spring 的项目中使用,它会在Autowired注解之后,init方法之前生效。

这个实现跟下面的差不多,举个例子

实例

其他代码参考下面的

@Component
public class InitTask implements CommandLineRunner {

    @Resource
    private Animal cat;

    @Autowired
    @Qualifier("dog")
    private Animal dog;
    @PostConstruct
    public void init(){
        //这里写实现
        //可以在另一个类里定义好静态属性和方法,在这里将内容填充进去

        AnimalFactory.produce("cat",cat);
        AnimalFactory.produce("dog",dog);
    }
}

CommandLineRunner

  1. 这是一个接口,用户可以自定义实现该接口,具体实现run方法
  2. 任何在上下文容器之内的bean都可以实现run方法
  3. 如果在上下文中,存在多个该接口实现类,可以通过@order注解,指定加载顺序

实例


@Component
public class InitTask implements CommandLineRunner {

    @Resource
    private Animal cat;

    @Autowired
    @Qualifier("dog")
    private Animal dog;

    @Override
    public void run(String... args) throws Exception {
        //这里写实现
        //可以在另一个类里定义好静态属性和方法,在这里将内容填充进去

        AnimalFactory.produce("cat",cat);
        AnimalFactory.produce("dog",dog);

    }
}

public class AnimalFactory {

    private static Map<String, Animal> animalMap=new HashMap<>();

    public static void produce(String name,Animal animal){
        animalMap.put(name,animal);
    }

    public static void lookup(String name){
        animalMap.get(name);
    }
}

ApplicationListener

ApplicationListener关注的是ApplicationEvent,spring中所有的事件都继承自ApplicationEvent,其中ApplicationContextEvent是主要的容器事件,它有容器启动、刷新、停止以及关闭各种事件的子类。
SpringApplicationEvent是和SpringApplication生命周期有关的所有事件的父类。
所以就本需求来说,我们主要关注ApplicationContextEvent的实现。
在这里插入图片描述

Spring提供如下几个内置事件:

》ContextRefreshEvent: ApplicationContext容器初始化或刷新触发该事件。此处的初始化是指,所有Bean 被成功装载,后处理Bean被检测并激发,所有Singleton Bean被预实例化,ApplicationContext容器已就绪可用。

》ContextStartedEvent: 当使用ConfigurableApplicationContext(ApplicationContext的子接口)接口的start()方法启动ApplicationContext容器时触发该事件。容器管理生命周期的Bean实例将获得一个指定的启动信号,这在经常需要停止后重新启动的场合比较常见。

》ContextClosedEvent:当使用ConfigurableApplicationContext接口的close()方法关闭ApplicationContext容器时触发该事件。

》ContextStoppedEvent:当使用ConfigurableApplicationContext接口的stop()方法使ApplicationContext停止时触发该事件。此处的“停止”意味着容器管理生命周期的Bean实例将获得一个指定的停止信号,被停止的Spring容器可在此调用start()方法重新启动。

》RequestHandledEvent:Web相关的事件,只能运用于使用DispatcherServlet的Web运用。在使用Spring作为前端的MVC控制器时,当Spring处理用户请求结束后,系统会自动触发该事件。

所以我们可以通过关注ContextRefreshEvent事件来实现需求。

实例

@Component
public class InitListener implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (Objects.isNull(event)){
            return;
        }
        ApplicationContext applicationContext=event.getApplicationContext();
        if (Objects.isNull(applicationContext)||Objects.isNull(applicationContext.getParent())){
            return;
        }

        Map<String, Animal> animalMap= BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext,Animal.class,false,false);
        if (Objects.isNull(animalMap)){
            throw new RuntimeException("未找到动物");
                    
        }
        for (Map.Entry<String,Animal> animal:animalMap.entrySet()){
            AnimalFactory.produce(animal.getKey(),animal.getValue());
        }
        
    }
}

参考

Spring ApplicationContext的事件机制
关于Spring JavaWeb工程中的ContextRefreshedEvent事件

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

山东大学机器学习期末2022

接力&#xff1a;山东大学机器学习期末2021 本来是不想写的&#xff0c;因为不想回忆起考试时啥也不会的伤痛&#xff0c;没想到最后给分老师海底捞&#xff0c;心情好了一些&#xff0c;还是一块写完 备考建议&#xff1a;多看ppt&#xff0c;多看ppt&#xff0c;多看ppt 山东…

关于 Android 线程优化这些知识你都该了解

前言在实际项目开发中会频繁的用到线程&#xff0c;线程使用起来是很简单&#xff0c;但是滥用线程会带来性能问题&#xff0c; 比如启动一个线程至少 占用16kb的内存、线程过多会导致cpu的频繁切换而cpu切换成本是很高的、消耗大量用户电量等问题&#xff0c; 所以应该让app的…

Set集合、HashSet集合、LinkedHashSet集合

1、Set集合的特点 无序&#xff0c;不重复、无索引 Set集合的方法上基本和Collection的API一致 2、Set集合的实现类特点 HashSet&#xff1a;无序、不重复、无索引 LinkedHashList&#xff1a;有序、不重复、无索引 TreeSet&#xff1a;可排序、不重复、无索引 public s…

taobao.fulfillment.order.assemble( 拆合单结果回传接口 )

&#xffe5;免费必须用户授权 拆合单结果回传接口 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 请求参数 响应参数 点击获取key和secret 请求示例 TaobaoClient client new DefaultTaobaoClient(url, appkey, secr…

centos7合并home分区到root分区

最近在尝试通过物理机安装 CentOS&#xff0c;官方镜像默认安装时&#xff0c;如果没有手动分区&#xff0c;默认设置是会将 home 单独分区&#xff0c;系统分区默认为 50 GB&#xff0c;这里提供方法将 home 分区合并到 root 分区。 1.查看当前系统分区情况 输入命令&#x…

华为OD机试用Python实现 -【删除重复数字后的最大数字】(2023-Q1 新题)

华为OD机试题 华为OD机试300题大纲删除重复数字后的最大数字题目输入输出示例一输入输出示例二输入输出Python 代码展示编码思路华为OD机试300题大纲 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:blog.csdn.ne…

RedisTemplate和StringRedisTemplate的区别

RedisTemplate和StringRedisTemplate的区别&#xff1a; 两者的关系是StringRedisTemplate继承RedisTemplate。两者的数据是不共通的&#xff1b;也就是说StringRedisTemplate只能管理StringRedisTemplate里面的数据&#xff0c;RedisTemplate只能管理RedisTemplate中的数据。…

图解鼠标事件的 ScreenX ,LayerX,clientX,PageX,offsetX,X

前言&#xff1a; 完在上一篇文章 &#x1f381;如何实现原生 JS 的拖拽效果我中使用到了 MouseEvent 事件对象身上的 clienX 的属性&#xff0c;但同时我也注意到了事件对象身上关于 X 的相关属性还有很多&#xff0c;并且在移动端开发中&#xff0c;这些属性需要频繁的用到&a…

golang 实现链表爽不爽?

犹记得刚学 C 语言的时候&#xff0c;学到指针这一章&#xff0c;就会有让我们写链表的需求&#xff0c;头插法&#xff0c;尾插法&#xff0c;翻转链表&#xff0c;合并链表&#xff0c;约瑟夫环等等 学的不亦乐乎&#xff0c;但是 对于指针刚学的时候&#xff0c;真是摸不着…

DolphinDB实现动量交易策略详解

动量策略是最流行的量化策略之一。商品期货的CTA策略&#xff0c;绝大多数都是基于动量策略。在股票市场&#xff0c;动量策略也是常用的量化因子之一。通俗地讲&#xff0c;动量策略就是“追涨杀跌”。下面我们将介绍如何在DolphinDB中测试动量交易策略&#xff0c;并计算动量…

第三阶段04-同步请求和异步请求,get/post,Josn,pojo,Session/Cookie,过滤器Filter

文章目录同步请求和异步请求客户端如何发出异步请求自定义模板代码Get和Post请求异步版本的注册和登录商品管理系统(异步版本)商品列表步骤:前后端分离为什么需要前后端分离?为什么以后不再使用同步请求?JSONPOJO会话对象Session如何记住登录状态后端的MVC会话管理Cookie通过…

交叉编译 iceoryx

交叉编译 iceoryx 概述 iceoryx 是用于各种操作系统的进程间通信&#xff08;IPC&#xff09;中间件&#xff08;目前支持 Linux、macOS、QNX、FreeBSD 和 Windows 10&#xff09;。它起源于汽车行业&#xff0c;当涉及到驾驶员辅助或自动驾驶系统时&#xff0c;需要在不同的过…

一起来学 next.js - getStaticProps、getStaticPaths 篇

之前讲过 next.js 中的 getServerSideProps&#xff0c;今天来讲一讲另一个很类似的 API&#xff1a;getStaticProps&#xff0c;以及和 getStaticProps 紧密相关的 getStaticPaths。 getStaticProps 主要用于构建时落地一些静态数据&#xff0c;但不同于 getServerSideProps&…

动态规划背包问题

背包问题的分类 拿到背包问题,最重要的是会归类到哪一种背包问题中,常见的考题里主要是01背包和完全背包,leetcode上连多重背包的题目都没有。实际完全背包问题就是01背包的一种。 对一和零这道题,很多人容易把m看成一个背包,n看成另一个背包,从而当做多重背包。然而这…

ChatGPT创业潮来了,我既兴奋又焦虑

最近一段时间&#xff0c;ChatGPT从AI领域破圈&#xff0c;成了互联网领域的新风口。创业者和投资人也兴奋起来了。 创业的方向已经很明了。做中国版对标ChatGPT的大模型&#xff0c;是显而易见的一条路。目前百度的“文心一言”已经呼之欲出&#xff0c;原美团联合创始人王慧…

超店有数分享:2023还有哪些tiktok数据值得关注?

目前&#xff0c;tiktok是全球增长最迅猛的社交媒体软件之一。很多商家瞄准了tiktok的变现转化潜力&#xff0c;纷纷入局tiktok电商赛道。在入局这个赛道之前&#xff0c;我们需要了解一些tiktok的相关数据&#xff0c;这样才能更好的了解大局&#xff0c;及时调整自己的业务情…

Swagger2基本使用

这里写目录标题废话篇前言什么是openAPISwagger简介Springfox使用篇swagger的基本使用废话篇 前言 接口文档对于前后端开发人员都十分重要。尤其近几年流行前后端分离后接口文档又变成重中之重。接口文档固然重要&#xff0c;但是由于项目周期等原因后端人员经常出现无法及时…

P21.为什么需要父子shell

脚本的不同执行方式是否会开启子shell 父Shell概念 &#xff08;1&#xff09;pstree查看父进程 如下命令安装pstree yum install -y psmiscsshd--sshd--bash--pstree 第一个sshd为操作系统自己启动的监听sshd服务的程序第二个sshd是shell连接过来启动的shell每次调用bash…

echarts scatter地图上渲染圆点

目录 实现效果实现步骤相关文件实现效果 如上图所示,我们经常遇到一些需求,在地图上根据数据的大小,再画一些直径不一的实心圆。 首先,我们得先把地图画好,再来画这些跟数据有关联的圆形。 为了方便scatter建立坐标系,我们采用geo来自定义绘制地图,而不是使用百度地图或…

前端面试题 —— 计算机网络(二)

目录 一、POST和PUT请求的区别 二、GET方法URL长度限制的原因 三、页面有多张图片&#xff0c;HTTP是怎样的加载表现&#xff1f; 四、HTTP2的头部压缩算法是怎样的&#xff1f; 五、说一下HTTP 3.0 六、HTTP协议的性能怎么样&#xff1f; 七、数字证书是什么&#xff1f…