Springboot最佳实践:在Spring Boot启动时添加方法运行(上)

简介: Springboot最佳实践:在Spring Boot启动时添加方法运行

在开发Spring Boot应用程序时,有时我们需要在启动时运行方法或一段代码。这段代码可以是任何内容,从记录某些信息到设置数据库,cron作业等。我们不能仅将此代码放入构造函数中,因为所需的变量或服务可能尚未初始化。这可能导致空指针或其他一些异常。

为什么我们需要在Spring Boot启动时运行代码?

由于多种原因,我们需要在应用程序启动时运行方法,

  • 记录重要的事情或说应用程序已启动的消息
  • 处理数据库或文件,建立索引,创建缓存等。
  • 启动后台进程,例如发送通知,从某些队列中获取数据等。

在Spring Boot中启动后运行方法的不同方法

每种方式都有其自身的优势。让我们详细看一下以确定应该使用哪个,

  1. 使用CommandLineRunner界面
  2. 带有ApplicationRunner界面
  3. Spring Boot应用程序事件
  4. @Postconstruct方法的注释
  5. InitializingBean接口
  6. @bean批注的Init属性

1.使用CommandLineRunner界面

CommandLineRunner是一个弹簧启动功能界面,用于在应用程序启动时运行代码。它位于软件包org.springframework.boot下。

在上下文初始化之后的启动过程中,spring boot使用提供给应用程序的命令行参数调用其run()方法。

要通知spring boot我们的commandlineRunner接口,我们可以实现它并在类上方添加@Component批注,或者使用@bean创建其bean。

实现CommandLineRunner接口的示例

@Component
public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("In CommandLineRunnerImpl ");
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

创建CommandLineRunner接口Bean的示

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class);
    }
    @Bean
    public CommandLineRunner CommandLineRunnerBean() {
        return (args) -> {
            System.out.println("In CommandLineRunnerImpl ");
            for (String arg : args) {
                System.out.println(arg);
            }
        };
    }
}

我们可以使用命令行或IDE运行应用程序。让我们举一个例子,当我们使用参数“ –status = running”运行应用程序时

mvn spring-boot:run -Dspring-boot.run.arguments="--status=running"

mvn package 
java -jar target/<FILENAME.JAR HERE> --status=running

这将产生以下日志输出:

In CommandLineRunnerImpl
status=running

如我们所见,该参数未解析,而是解释为单个值“ status = running”。

要访问已解析格式的命令行参数,我们需要使用ApplicationRunner接口。我们待会儿再看。

Spring Boot将CommandLineRunner接口添加到启动过程中。因此,在commandlinerRunner中引发异常将迫使Spring启动中止启动。

我们可以在一个应用程序中创建多个CommandLineRunner。使用Ordered接口或@Order批注,我们可以配置它们的运行顺序。较低的值表示较高的优先级。默认情况下,所有组件均以最低优先级创建。这就是为什么没有订单配置的组件将被最后调用的原因。

我们可以使用订单注释,如下所示

@Component
@Order(1)
public class CommandLineRunnerImpl implements CommandLineRunner {
    ........
}

2.具有ApplicationRunner界面

如前所述,要访问已解析的参数,我们需要使用ApplicationRunner接口。ApplicationRunner接口为运行方法提供ApplicationArguments而不是原始字符串数组。

ApplicationArguments是一个接口,可从org.springframework.boot软件包下的boot 1.3 srping中获得。

它提供了以下几种访问参数的方法

String [] GetSourceArgs() 提供传递给应用程序的未处理参数
Set <String> getOptionNames() 所有可选参数的名称,可选参数的前面都有“ - “如:-name =‘堆栈跟踪’
List <String> getNonOptionArgs() 返回未处理的非可选参数。不带“  ”的参数
布尔containsOption(字符串名称)  检查在可选参数中是否存在名称
List <String> getOptionValues(字符串名称) 通过名称给出参数值

方法getOptionValues返回值列表,因为参数值可以是数组,因为我们可以在命令行中多次使用同一键。

例如–name =“ stacktrace” —端口= 8080 –name =“ guru”

作为接口实现的应用程序运行器示例

让我们使用“ status = running –mood = happy 10 –20”参数运行以下程序,并了解输出

@Component
public class ApplicationRunnerImpl implements ApplicationRunner {
   @Override
   public void run(ApplicationArguments args) throws Exception {
      System.out.println("ApplicationRunnerImpl Called");
//print all arguemnts: arg: status=running, arg: --mood=happy, 10, --20
      for (String arg : args.getSourceArgs()) {
         System.out.println("arg: "+arg);
      }
      System.out.println("NonOptionArgs: "+args.getNonOptionArgs()); //[status=running,10]
      System.out.println("OptionNames: "+args.getOptionNames());  //[mood, 20]
     System.out.println("Printing key and value in loop:");
      for (String key : args.getOptionNames()) {
         System.out.println("key: "+key);     //key: mood  //key: 20
         System.out.println("val: "+args.getOptionValues(key)); //val:[happy] //val:[]
      }
   }
}

输出:

ApplicationRunnerImpl Called
arg: status=running
arg: --mood=happ
arg: 10
arg: --20
NonOptionArgs: [status=running , 10]
OptionNames: [mood, 20]
Printing key and value in loop:
key: mood
val: [happy]
key: 20
val: []

CommandLineRunner和ApplicationRunner具有类似的功能,例如

  • run()方法中的异常将中止应用程序启动
  • 可以使用Ordered接口或@Order批注来订购多个ApplicationRunner

需要注意的最重要一点是,命令在CommandLineRunners和ApplicationRunners之间共享。这意味着可以在commandlinerRunner和applicationRunner之间混合执行顺序。

目录
相关文章
|
12天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
17 1
|
13天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
23 1
|
17天前
|
存储 安全 Java
|
27天前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
52 2
|
27天前
|
前端开发 Java 程序员
springboot 学习十五:Spring Boot 优雅的集成Swagger2、Knife4j
这篇文章是关于如何在Spring Boot项目中集成Swagger2和Knife4j来生成和美化API接口文档的详细教程。
48 1
|
28天前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
19 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
28天前
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
21 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
28天前
|
Java 测试技术 Spring
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
这篇文章介绍了Spring Boot中配置文件的语法、如何读取配置文件以及如何通过静态工具类读取配置文件。
41 0
springboot学习三:Spring Boot 配置文件语法、静态工具类读取配置文件、静态工具类读取配置文件
|
1月前
|
JSON 缓存 Java
优雅至极!Spring Boot 3.3 中 ObjectMapper 的最佳实践
【10月更文挑战第5天】在Spring Boot的开发中,ObjectMapper作为Jackson框架的核心组件,扮演着处理JSON格式数据的核心角色。它不仅能够将Java对象与JSON字符串进行相互转换,还支持复杂的Java类型,如泛型、嵌套对象、集合等。在Spring Boot 3.3中,通过优雅地配置和使用ObjectMapper,我们可以更加高效地处理JSON数据,提升开发效率和代码质量。本文将从ObjectMapper的基本功能、配置方法、最佳实践以及性能优化等方面进行详细探讨。
47 2
|
10天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
15 0
下一篇
无影云桌面