Springboot 初始化操作

news2024/9/25 21:28:29

文章目录

  • 程序启动后的初始化
    • ApplicationRunner 接口
    • CommandLineRunner 接口
    • ApplicationRunner 和CommandLineRunner 的区别
  • Bean的实例化
    • InitializingBean 接口
    • @PostConstruct注解
    • @Bean
    • InitializingBean 接口、@PostConstruct注解、@Bean注解区别
  • 总结

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

在使用Springboot过程中,或多或少我们会遇到在Springboot启动时要初始化类,或者加载文件之类的一些操作。关于初始化,主要分为两类,一类是在程序启动后的执行初始化操作,另一类是Bean实例化时执行初始化操作,本文将介绍这两类初始化操作常用的一些类和注解,相信总会有一种方法适合你的。

程序启动后的初始化

ApplicationRunner 接口

ApplicationRunner接口主要作用是在应用程序启动完成后执行一些自定义的逻辑。通过实现ApplicationRunner接口并重写其run方法,我们可以定义在应用程序启动后需要执行的任务逻辑。当Spring Boot应用程序启动完成后,ApplicationRunner接口的run方法会被自动调用,执行你在该方法中定义的任务。

ApplicationRunner接口特别适用于那些需要在应用程序启动后立即执行的任务,例如数据初始化、缓存预热等。此外,它也常被用作定时任务的触发点,在应用程序启动时即启动一些定时任务。

run方法中,我们可以通过传入的ApplicationArguments对象获取到启动应用程序时传递的命令行参数,这为我们提供了更多的灵活性和控制力。

以下是一个简单的示例,演示了如何使用 ApplicationRunner 接口:

/**
 * @author 公众号(索码理)
 */
@Component
public class MyApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("ApplicationRunner 执行初始化操作...");

        // 获取命令行参数的值
        String name = args.getOptionValues("name").get(0); // 获取名为"name"的参数的值
        boolean hasCode = args.containsOption("code"); // 检查是否存在名为"code"的标志

        System.out.println("name: " + name);
        System.out.println("hasCode: " + hasCode);
        System.out.println("=============分割线=============");
    }
}

idea中设置启动参数:

控制台输出结果:

在这个示例中,我们使用getOptionValues()方法来获取命令行参数的值,该方法返回一个字符串列表。如果参数是标志而不是键值对,则可以使用containsOption()方法检查参数是否存在。从控制台中我们可以看到 ApplicationRunner 接口的初始化操作是在Tomcat启动之后即程序启动之后进行初始化的。

CommandLineRunner 接口

CommandLineRunner 接口是 Spring Boot 中的一个功能性接口,用于在 Spring Boot 应用程序启动后执行特定的任务或代码。我们可以使用它在 Spring Boot 应用程序启动后执行一些初始化操作,例如加载初始数据、执行特定的业务逻辑、启动后台任务等。

这个接口只定义了一个方法 run(String... args),该方法在 Spring Boot 应用程序启动后会被自动调用,其中 args 参数是命令行参数。开发者需要实现这个接口,并在实现类中编写需要在应用程序启动后执行的代码逻辑。

Spring Boot 在启动时会自动检测所有实现了 CommandLineRunner 接口的 bean,并在应用程序启动后按照它们在 Spring 上下文中的注册顺序依次调用其 run 方法。

使用 CommandLineRunner 接口可以方便地进行应用程序启动后的初始化工作,而不需要显式地编写启动时的逻辑,从而使应用程序的启动过程更加灵活和可扩展。

以下是一个简单的示例,演示了如何使用 CommandLineRunner 接口:

import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

/**
 * @author 公众号(索码理)
 */
@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("CommandLineRunner 执行初始化操作...");
        System.out.println("CommandLineRunner args = " + Arrays.toString(args));
    }
}

在这个示例中,我们创建了一个名为 MyCommandLineRunner 的类,它实现了 CommandLineRunner 接口,并重写了 run 方法,在方法中打印参数表示应用程序启动成功。从控制台中我们可以看到 CommandLineRunner 接口的初始化操作是在Tomcat启动之后即程序启动之后进行初始化的。

ApplicationRunner 和CommandLineRunner 的区别

了解完ApplicationRunnerCommandLineRunner 接口之后,不难发现,它们都是在程序启动后执行特定操作的,那它们之间有什么不同呢?

ApplicationRunnerCommandLineRunner 接口都继承了Runner接口, 它们之间的区别主要在于方法签名传递参数的方式:

  1. 方法签名

    • CommandLineRunner 接口中的 run 方法签名为 void run(String... args),其中参数 args 是一个字符串数组,用于接收命令行参数。
    • ApplicationRunner 接口中的 run 方法签名为 void run(ApplicationArguments args),其中参数 argsApplicationArguments 类型的对象,用于接收应用程序的启动参数。
  2. 参数传递方式

    • CommandLineRunner 中,启动参数是作为字符串数组直接传递给 run 方法的参数。
    • ApplicationRunner 中,启动参数是作为 ApplicationArguments 对象传递给 run 方法的参数,这个对象提供了更丰富的参数处理功能,例如获取非标准的命令行参数、获取命令行参数的选项和值等。

在大多数情况下,这两个接口可以互换使用,选择哪一个主要取决于对命令行参数处理的需求。如果你只需要简单地接收命令行参数,那么使用 CommandLineRunner 就足够了。但如果你需要更复杂的参数处理,例如获取命令行参数的选项和值,那么使用 ApplicationRunner 会更方便。

另外,需要注意的是,Spring Boot 在启动时会优先调用实现了 ApplicationRunner 接口的 bean 的 run 方法,如果没有找到 ApplicationRunner 类型的 bean,则会去调用实现了 CommandLineRunner 接口的 bean 的 run 方法。

Bean的实例化

InitializingBean 接口

InitializingBean 接口是Spring框架的一个接口,它允许Bean在其属性被设置后进行自定义初始化操作。这个接口定义了一个方法afterPropertiesSet(),在Bean的所有属性被设置后立即调用。
这使得 InitializingBean 可以作为自定义初始化回调的标记接口,用于执行那些需要在对象依赖注入完成之后进行的初始化操作。

通过实现InitializingBean接口,可以确保在Spring容器完成Bean的实例化和属性设置后执行特定的初始化逻辑。这在需要在Bean初始化阶段执行一些特定操作时非常有用,例如数据验证、资源初始化或与其他Bean的交互等。

以下是一个简单的示例,演示了如何实现InitializingBean接口:

/**
 * @author sunlong
 * @author 公众号(索码理)
 */
public class MyInitializingBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean 执行初始化操作...");
    }
}

注入MyInitializingBean 实例:

@Configuration
public class ServiceConfig {
    @Bean
    public MyInitializingBean MyInitializingBean() {
        System.out.println("MyInitializingBean 注入。。。");
        return new MyInitializingBean();
    }
}

控制台打印结果:

MyInitializingBean 注入。。。
InitializingBean 执行初始化操作...

在这个例子中,当Spring容器实例化MyInitializingBean 时,会自动调用afterPropertiesSet()方法来执行初始化逻辑。

@PostConstruct注解

@PostConstruct注解是Java EE 5规范中引入的一个注解,主要在JSR 250标准中定义。它被设计用于在对象实例化后、依赖注入完成之时自动调用某个方法,以执行初始化操作。这个注解通常用于Java EE和Spring等框架中,标记那些需要在依赖注入后执行的方法。

其主要用途包括在依赖注入完成后,执行一些需要依赖注入对象的初始化逻辑。例如,你可以在@PostConstruct注解的方法中进行一些属性的赋值、资源的初始化、连接的建立等操作。

在Spring框架中,当Spring创建了一个类的实例并完成依赖注入后,如果该类中存在被@PostConstruct注解的方法,Spring会自动调用这个方法。需要注意的是,@PostConstruct注解只能用于非静态方法,并且只会被容器调用一次。如果一个类中存在多个被@PostConstruct注解的方法,它们的执行顺序并不确定,但你可以通过@Order注解来指定执行顺序。

在Spring项目中,一个bean的初始化过程中,方法执行的先后顺序为:Constructor > @Autowired > @PostConstruct。即首先执行构造方法,然后进行依赖注入,最后执行初始化操作。

关于@PostConstruct注解的方法,它可以有返回值,尽管通常我们将其返回类型设置为void。而且,这个方法的访问修饰符可以是publicprotectedprivate,因为它的功能是通过反射来实现的。此外,这个方法不能是static的,但可以是final的。

InitializingBean接口相比,@PostConstruct注解提供了更清晰、更灵活的方式来定义初始化方法,而且不需要实现任何特定的接口。

以下是一个简单的示例,演示了如何实现**@PostConstruct**注解:

@Component
public class PostConstructComponent {

    @PostConstruct
    public void init() {
        // 执行初始化操作
        System.out.println("PostConstruct执行初始化操作...");
    }
}

在这个示例中,当Spring容器实例化PostConstructComponent 并完成依赖注入后,会调用init()方法来执行初始化逻辑。

@Bean

@Bean注解主要用于将对象(通常是bean)存入Spring的IoC)容器中。与@Controller@Service@Repository@Component等类注解不同,@Bean注解是方法级别的,它通过将当前方法的返回值对象放入容器中来实现对象的管理。通过这种方式我们可以自定义bean的创建逻辑。

在Spring配置类中,你可以使用@Bean注解来定义一个或多个bean。默认情况下,bean的名称与带有@Bean注解的方法名相同,但你也可以使用name属性来指定一个自定义的名称。

@Bean注解有一个initMethod属性,用于指定bean的初始化方法。

例如:

创建MyService 类:

public class MyService {
    public void initMethod() {
        System.out.println("MyService 执行初始化操作...");
    }
}

注入MyService

@Configuration
public class ServiceConfig {

    @Bean(initMethod = "initMethod")
    public MyService myService() {
        System.out.println("MyService 注入。。。");
        return new MyService();
    }
}

在这个例子中,MyService的实例会被创建,并且作为名为myService的bean注册到Spring容器中,在MyService被实例化时,会自动调用MyServiceinitMethod方法。

InitializingBean 接口、@PostConstruct注解、@Bean注解区别

InitializingBean接口、@PostConstruct注解和@Bean注解在Spring框架中都有各自的作用,尽管它们都可以用于执行Bean的初始化逻辑,但它们还是有所区别的:

  • InitializingBean@PostConstruct主要用于执行Bean的初始化逻辑,但它们来源于不同的框架或规范。InitializingBean是Spring特有的,而@PostConstruct是Java EE规范的一部分,由Java EE容器调用。
  • @Bean主要用于声明和定义Bean,虽然可以在其方法内部执行初始化逻辑,但其主要目的是定义和注册Bean。
  • InitializingBean@PostConstruct都可以在Bean的属性被注入之后执行初始化逻辑,但@PostConstruct的方法在InitializingBeanafterPropertiesSet()方法之前执行。

在Spring中,通常推荐使用@PostConstruct注解来执行初始化逻辑,因为它更符合Java EE规范,并且与Spring的依赖注入机制结合得更好。

总结

本文介绍了程序启动后和Bean实例化后可以进行的初始化操作,有生就有死,能够初始化就能够销毁,下篇文章将介绍如何在程序关闭时和Bean销毁时进行一系列操作,感兴趣可以关注一下,敬请期待。

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

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

相关文章

晨控电子纸,工业无纸化新方案

一款好的产品,应该用心的去介绍。随着工业科技不断的迭代,生产车间自动化程度越来越高,但很多工序还是需要人员去更换,确认生产流程单。由于人员确认流程单的不确定性,很有可能出现流程单信息错误,下一工序…

Excel文件解析--超大Excel文件读写

使用POI写入 当我们想在Excel文件中写入100w条数据时,我们用普通的XSSFWorkbook对象写入时会发现,只有在将100w条数据全部加载入内存后才会用write()方法统一写入,这样效率很低,所以我们引入了SXSSFWorkbook进行超大Excel文件的读…

《ElementUI 基础知识》png 图片扩展 icon用法

前言 UI 设计给的切图是 .png 格式。但想与 Element UI icon 用法类似,方案如下。 实现 步骤一 准备图片 步骤二 新建文件,可使用 CSS 预处理语言 styl 或 scss。 stylus 方式 文件 icon.styl /* 定义一个混合 */ cfgIcon(w, h) {display: inlin…

二叉搜索树中的搜索(力扣700)

解题思路:因为二叉搜索树的左小右大特点,中只是寻找比较目标,怎么序遍历都可以,终止条件就是遍历完毕和找到了,然后就遍历左右子树开始寻找就好了 具体代码如下: class Solution { public: TreeNode* searchBST(Tre…

Java入门四步走

1. 简单的入门语法: 1.1 数据类型: 基本数据类型: 整数类型 —— byte、short、int、long, 浮点类型 —— float、double 字符类型 —— char 布尔类型 —— boolean 引用数据类型: 接口(interface)、数…

上市公司-企业数据要素利用水平数据集及参考文献(2010-2022年)

01、数据介绍 企业数据要素利用水平是指企业在其生产经营活动中,对数据的收集、处理、分析和应用的能力及效果。这种利用水平的高低直接反映了企业在数字化时代中的竞争力和创新能力。 本数据参考《中央财经大学学报》史青春(2023)老师的研…

芒果超媒的“乘风破浪”,差了一点市场海浪的反馈

4月21日晚间,芒果超媒发布了2023年度&2024一季度报告。 芒果超媒2023年实现营业收入146.28亿元,同比增长4.66%;净利润35.56亿元,同比增长90.73%;基本每股收益1.90元。公司拟每10股派发现金红利1.8元。2024年第一季…

使用gdal均匀筛选点矢量

使用gdal均匀筛选点矢量 作用: 通过计算各点之间的欧式距离,筛选出符合目标的、均匀发布在空间中的N个数据点。 效果示意图 运行环境 python 3.10 安装:tqdm、numpy和tqdm这三个库 完整代码 import numpy as np from osgeo import ogr,…

291个地级市资源错配指数、劳动和资本相对扭曲指数(2006-2021年)

01、数据介绍 资源错配指数(Misallocation Index)是一个用于衡量资源配置效率的指标,它衡量的是生产要素的配置是否合理,是否达到了最优的状态。资源错配指数越高,资源的利用效率越低。资源错配指数主要用于衡量各种生…

没想到打脸这么快,AI程序员已经出发了!

大家好啊,我是豆小匠。 先介绍一下本期的主角:Devin,世界上第一位AI程序员,由2023年11月成立的10人初创公司Cognition AI开发。 1. AI程序员已经能做到什么程度 3月13日,Cognition AI公司在X平台(原推特&…

监控员工上网记录软件 三款超好用监控员工上网的软件

监控员工上网记录软件 三款超好用监控员工上网的软件 监控员工上网聊天、打游戏、看小说等特定行为的软件通常属于员工监控或上网行为管理软件类别。这类软件旨在帮助企业或组织管理者监督员工在工作时间内对计算机及互联网资源的使用情况,确保工作效率,…

进阶C语言-文件操作

文件操作 🎈1.为什么使用文件🎈2.什么是文件🔭2.1程序文件🔭2.2数据文件🔭2.3文件名 🎈3.文件的打开和关闭🔭3.1文件指针🔭3.2文件的打开和关闭 🎈1.为什么使用文件 ✅ 我…

vue的学习之用vue写一个hello,vue

根据以下步骤下载vue.js 介绍 — Vue.js 创建一个damo.html &#xff0c;引入vue.js即可 <body><div id"app">{{ message }}</div><!-- Vue --><!-- 开发环境版本&#xff0c;包含了有帮助的命令行警告 --><script src"js/vu…

Mysql基础(二)数据类型和约束

一 数据类型 讲解主要的数据类型,不面面俱到,后续遇到具体问题再查询补充扩展&#xff1a; 知识点的深度和广度以工作为导向 ① int float M : 表示显示宽度&#xff0c;M的取值范围是(0, 255)例如: int(5),当数据宽度小于5位的时候在数字前面需要用字符填满宽度说明&…

2元4mm2高精度温度湿度传感器GXHTC3

温湿度传感器芯片GXHTC3 前言&#xff1a; 该温湿度传感器为国产&#xff0c;批量价格约2元&#xff0c;精度较高&#xff0c;DHT11该被淘汰了&#xff0c;这个才是传感器。 特点 超低功耗 宽工作电压范围(1.62 – 5.5 V) 小型 DFN 封装: 2 2 0.75 mm3 典型精度: 湿度 2 %R…

量子城域网系列(五):几种典型的量子密钥分发网络组网结构

在上之前文章中&#xff0c;我们介绍了最基本的点对点量子保密通信网络形式以及组网方案&#xff0c;但是显然在实际的应用中&#xff0c;点对点的通信是比较少的&#xff0c;大多还是需要多个终端进行互联才能构成网络。本文我们就讨论一下几种基础的量子密钥分发网络组网结构…

基于云计算技术的HIS系统,一体化云HIS、云病历、云LIS系统源码,扩展后能够应用于医联体/医共体

医院信息管理系统云HIS系统源码&#xff0c;云计算技术的HIS系统源码 开发技术&#xff1a; 前端&#xff1a;AngularNginx&#xff1b; 后台&#xff1a;JavaSpring&#xff0c;SpringBoot&#xff0c;SpringMVC&#xff0c;SpringSecurity&#xff0c;MyBatisPlus 等&…

使用【node】创建本地接口

在前端开发的过程中&#xff0c;接口相关的信息一般是由后端处理好返回给前端&#xff0c;但是有时候后端不在的时候想自己写个接口进行测试是非常麻烦的。 node是前端一个不错的写接口工具 一 初始化文件 1 在新建一个空的文件夹node 进入空文件夹在&#xff0c;文件夹的地…

《庆余年》开发衍生短剧,阅文迈向短剧市场的一大步

《庆余年》竟然也要拍短剧了。 据悉&#xff0c;《庆余年》衍生短剧《庆余年之少年风流》预计将于5月1日开机&#xff0c;等了五年都没等到《庆余年2》&#xff0c;没想到先等到了衍生短剧。 由组讯消息可知&#xff0c;《庆余年之少年风流》讲述的是少年庆帝李云潜“扮猪吃老…

一道有意思的面试题

面试过程中没有想到合适的数据结构&#xff0c;想了半天&#xff0c;构思没有实践落地。 也是听错了&#xff0c;以为三道题都要做&#xff0c;做出来了两道&#xff0c;这道死活没落地成功。 结果&#xff0c;三道题里面任选一道就行。。。。 好吧 题目&#xff1a;给定一个…