spring_在Spring Boot启动时运行方法

spring

spring

在开发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 =“ stacktrace”
List <String> getNonOptionArgs() 返回未处理的非可选参数。 不带 ”的参数
布尔containsOption(字符串名称) 检查在可选参数中是否存在名称
List <String> getOptionValues(字符串名称) 通过名称给出参数值

方法getOptionValues返回值列表,因为参数值可以是数组,因为我们可以在命令行中多次使用同一键。例如–name =“ stacktrace” —端口= 8080 –name =“ guru”

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

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

String [] GetSourceArgs()

输出:

String [] GetSourceArgs()

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

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

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

3. Spring Boot中的应用程序事件

Spring框架在不同情况下触发不同事件。 它还会在启动过程中触发许多事件。 我们可以使用这些事件来执行代码,例如,在Spring Boot应用程序启动后,可以使用ApplicationReadyEvent执行代码。

如果我们不需要命令行参数,这是在应用程序启动后执行代码的最佳方法。

String [] GetSourceArgs()

输出:

String [] GetSourceArgs()

Sprint Boot子中最重要的事件是

  • ApplicationContextInitializedEvent :在准备ApplicationContext并调用ApplicationContextInitializers之后但在加载bean定义之前触发
  • ApplicationPreparedEvent :在加载bean定义后触发
  • ApplicationStartedEvent :在刷新上下文之后但在调用命令行和应用程序运行程序之前触发
  • ApplicationReadyEvent :在调用任何应用程序和命令行运行程序之后触发
  • ApplicationFailedEvent :如果启动时发生异常则触发

可以创建多个ApplicationListeners。 可以使用@Order批注或O​​rdered接口对其进行订购。

该顺序与其他相同类型的ApplicationListener共享,但不与ApplicationRunners或CommandLineRunners共享。

4.方法上的@Postconstruct注解

可以使用@PostConstruct批注标记方法。 每当使用此注释标记方法时,将在依赖项注入后立即调用该方法。

@PostConstruct方法链接到特定的类,因此它仅应用于特定于类的代码。 每个类只有一个带有postConstruct批注的方法。

String [] GetSourceArgs()

输出:

String [] GetSourceArgs()

需要注意的是,如果class标记为lazy,则意味着在请求时创建了class。 之后,将执行标有@postConstruct批注的方法。

标有postConstruct批注的方法可以具有任何名称,但是不能具有任何参数。 它必须是无效的,并且不能是静态的。

请注意,@postConstruct批注是Java EE模块的一部分,在Java 9中被标记为已弃用,在Java 11中已被删除。我们仍然可以通过将java.se.ee添加到应用程序中来使用它。

5. InitializingBean接口

InitializingBean解决方案的工作原理与postConstruct批注完全相似。 不必使用注释,我们必须实现InitializingBean接口。 然后,我们需要重写afterPropertiesSet()方法。

InitializingBean是org.springframework.beans.factory包的一部分。

String [] GetSourceArgs()

您必须考虑如果同时使用@PostConstruct批注和InitializingBean会发生什么。 那么在这种情况下,@PostConstruct方法将在InitializingBean的afterPropertiesSet()方法之前调用。

6. @bean批注的init属性

我们可以在@Bean批注中使用initMethod属性提供一种方法。 bean初始化后将调用此方法。

initMethod中提供的方法必须为空,并且不能包含任何参数。 此方法甚至可以是私有的。

String [] GetSourceArgs()

输出:

String [] GetSourceArgs()

如果您具有同一类的InitializingBean实现和@Bean批注的initMethod属性,则将initMethod之前调用InitializingBean的afterPropertiesSet方法。

结合不同的方法:

最后,有时我们可能需要组合多个选项。 然后,它们将按照以下顺序执行:

  • 建设者
  • 后构造方法
  • afterPropertiesSet方法
  • Bean初始化方法
  • ApplicationStartedEvent
  • ApplicationRunner或CommandLineRunner取决于顺序
  • ApplicationReadyEvent

快速阅读

  • Spring启动应用程序启动后,有多种方法可以运行代码
  • 我们可以使用CommandLineRunner或ApplicationRunner接口
  • 使用ApplicationRunner接口访问已解析的参数,而不是原始字符串数组
  • Spring Boot事件在应用程序启动时执行代码
  • 标有@PostConstruct批注的方法在对象初始化后执行
  • 对象初始化之后调用InitializingBean接口的afterPropertiesSet()方法
  • @Bean批注具有属性“ initMethod”以提供将在bean初始化后调用的方法

相关话题

翻译自: https://www.javacodegeeks.com/2020/10/run-method-on-spring-boot-startup.html

spring

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值