springboot项目启动成功后执行一段代码的两种方式

springboot项目启动成功后执行一段代码的两种方式| Id | Title | DateAdded | SourceUrl | PostType | Body | BlogId | Description | DateUpdated | IsMarkdown | EntryName | CreatedTime | IsActive | AutoDesc | AccessPermission |

| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------| -------------|
| 14939677| springboot项目启动成功后执行一段代码的两种方式| 2021-06-27T01:23:00| | BlogPost|

实现ApplicationRunner接口

复制代码
复制代码
package com.lnjecit.lifecycle;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**

  • @author lnj
  • createTime 2018-11-07 22:37
    **/
    @Component
    public class ApplicationRunnerImpl implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
    System.out.println("通过实现ApplicationRunner接口,在spring boot项目启动后打印参数");
    String[] sourceArgs = args.getSourceArgs();
    for (String arg : sourceArgs) {
    System.out.print(arg + " ");
    }
    System.out.println();
    }
    }
复制代码
复制代码

 

项目启动后,会打印如下信息:

 

 

实现CommandLineRunner接口

复制代码
复制代码
package com.lnjecit.lifecycle;

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

/**

  • @author lnj
  • createTime 2018-11-07 22:25
    **/
    @Component
    public class CommandLineRunnerImpl implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
    System.out.println("通过实现CommandLineRunner接口,在spring boot项目启动后打印参数");
    for (String arg : args) {
    System.out.print(arg + " ");
    }
    System.out.println();
    }
    }
复制代码
复制代码

 

 

 两种实现方式的不同之处在于run方法中接收的参数类型不一样

 

指定执行顺序

当项目中同时实现了ApplicationRunner和CommondLineRunner接口时,可使用Order注解或实现Ordered接口来指定执行顺序,值越小越先执行

 

原理

通过调试可以发现都是在 org.springframework.boot.SpringApplication#run(java.lang.String...)方法内的afterRefresh(上下文刷新后处理)方法时,会执行callRunners方法。

afterRefresh方法具体实现如下: 

protected void afterRefresh(ConfigurableApplicationContext context,
        ApplicationArguments args) {
    callRunners(context, args);
}

callRunners方法具体实现如下: 

复制代码
复制代码
private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<Object>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<Object>(runners)) {
        if (runner instanceof ApplicationRunner) {
            callRunner((ApplicationRunner) runner, args);
        }
        if (runner instanceof CommandLineRunner) {
            callRunner((CommandLineRunner) runner, args);
        }
    }
}
复制代码
复制代码

 可以看出上下文完成刷新后,依次调用注册的runners, runners的类型为 ApplicationRunner 或 CommandLineRunner

 

案例地址

https://github.com/linj6/springboot-learn/tree/master/springboot-runner

 

参考资料

https://blog.csdn.net/zknxx/article/details/52196427

| 648658| | 2024-04-29T21:16:00| false| | 2021-06-27T01:23:20.467| true| 实现ApplicationRunner接口 package com.lnjecit.lifecycle; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.Application| Anonymous|
posted @   RalphLauren  阅读(235)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示