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

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


需求

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

实现

@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事件

相关文章
|
9月前
|
IDE 安全 Java
Lombok 在企业级 Java 项目中的隐性成本:便利背后的取舍之道
Lombok虽能简化Java代码,但其“魔法”特性易破坏封装、影响可维护性,隐藏调试难题,且与JPA等框架存在兼容风险。企业级项目应优先考虑IDE生成、Java Records或MapStruct等更透明、稳健的替代方案,平衡开发效率与系统长期稳定性。
559 115
|
9月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
9月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
790 1
|
9月前
|
Java API 开发工具
【Azure Developer】Java代码实现获取Azure 资源的指标数据却报错 "invalid time interval input"
在使用 Java 调用虚拟机 API 获取指标数据时,因本地时区设置非 UTC,导致时间格式解析错误。解决方法是在代码中手动指定时区为 UTC,使用 `ZoneOffset.ofHours(0)` 并结合 `withOffsetSameInstant` 方法进行时区转换,从而避免因时区差异引发的时间格式问题。
405 4
|
9月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
572 16
|
10月前
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
10月前
|
前端开发 Java API
2025 年 Java 全栈从环境搭建到项目上线实操全流程指南:Java 全栈最新实操指南(2025 版)
本指南涵盖2025年Java全栈开发核心技术,从JDK 21环境搭建、Spring Boot 3.3实战、React前端集成到Docker容器化部署,结合最新特性与实操流程,助力构建高效企业级应用。
3004 1
|
10月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
10月前
|
JavaScript Java 微服务
现代化 Java Web 在线商城项目技术方案与实战开发流程及核心功能实现详解
本项目基于Spring Boot 3与Vue 3构建现代化在线商城系统,采用微服务架构,整合Spring Cloud、Redis、MySQL等技术,涵盖用户认证、商品管理、购物车功能,并支持Docker容器化部署与Kubernetes编排。提供完整CI/CD流程,助力高效开发与扩展。
1079 64
|
11月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
957 0