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

16 篇文章 1 订阅

需求

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

实现

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中的存储过程是一段预先编译好的SQL代码,可以在需要时调用。存储过程通常在服务器端执行,可以大大减少客户端与服务器之间的数据传输量,提高数据库的执行效率。在Java中,可以使用JDBC(Java Database Connectivity) API来调用存储过程。 下面是一个简单的Java程序示例,用于调用MySQL数据库中的一个存储过程: ```java import java.sql.*; public class CallStoredProcedure { public static void main(String[] args) { try { // 加载MySQL JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); // 连接到数据库 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase", "root", "password"); // 创建CallableStatement对象,用于调用存储过程 CallableStatement cs = conn.prepareCall("{call my_stored_procedure(?, ?, ?)}"); // 设置存储过程参数 cs.setInt(1, 100); cs.setString(2, "John"); cs.setString(3, "Doe"); // 执行存储过程 cs.execute(); // 获取存储过程的输出参数 int result = cs.getInt(1); // 关闭连接和Statement对象 cs.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的示例中,我们通过JDBC API连接到MySQL数据库,并使用CallableStatement对象调用了一个名为my_stored_procedure的存储过程。存储过程有三个输入参数,分别为整型、字符串和字符串类型,然后执行存储过程并获取其输出参数。最后,关闭连接和Statement对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盖丽男

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值