【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口

2024-06-04 3816阅读

1. ApplicationRunner接口

用法:

  • 类型: 接口

  • 方法: 只定义了一个run方法

  • 使用场景: springBoot项目启动时,若想在启动之后直接执行某一段代码,就可以用 ApplicationRunner这个接口,并实现接口里面的run(ApplicationArguments args)方法,方法中写上自己的代码逻辑。也就是:spring容器启动完成之后,就会紧接着执行这个接口实现类的run方法。

  • run方法的参数: ApplicationArguments可以获取到当前项目执行的命令参数。(比如把这个项目打成jar执行的时候,带的参数可以通过ApplicationArguments获取到);

    @Component  //此类一定要交给spring管理
    public class ConsumerRunner implements ApplicationRunner{
         @Override
         public void run(ApplicationArgumers args) throws Exception{
            //代码
            System.out.println("需要在springBoot项目启动时执行的代码---");
         }
    }
    

    若有多个代码段需要执行,可用@Order注解设置执行的顺序。

    在同一个项目中,可以定义多个ApplicationRunner的实现类,他们的执行顺序通过注解@Order注解或者再实现Ordered接口来实现。

    @Order注解: 如果有多个实现类,而你需要他们按一定顺序执行的话,可以在实现类上加上@Order注解。@Order(value=整数值)。SpringBoot会按照@Order中的value值从小到大依次执行。

    @order, 使用注解方式使bean的加载顺序得到控制;@Order标记定义了组件的加载顺序,值越小拥有越高的优先级,可为负数。值越小,越先被加载。

    @Order(-1) 优先于 @Order(0)

    @Order(1) 优先于 @Order(2)

    @Component  //此类一定要交给spring管理
    @Order(value=1) //首先执行
    public class ConsumerRunnerA implements ApplicationRunner{
        @Override
        public void run(ApplicationArgumers args) throws Exception{
            //代码
            System.out.println("需要在springBoot项目启动时执行的代码1---");
        }
    }
    
    @Component  //此类一定要交给spring管理
    @Order(value=2) //其次执行
    public class ConsumerRunnerB implements ApplicationRunner{
        @Override
        public void run(ApplicationArgumers args) throws Exception{
            //代码
            System.out.println("需要在springBoot项目启动时执行的代码2---");
        }
    }
    

    @Component注解: 将类注入到spring容器中。

    参考链接:https://blog.csdn.net/hc1285653662/article/details/122445495

    2. CommandLineRunner接口

    用法:

    在容器启动成功后的最后一步回调(类似开机自启动)

    写一个类,实现CommandLineRunner接口,将该类注入到Spring容器中;

    可以通过@Order注解(属性指定数字越小表示优先级越高)或者Ordered接口来控制执行顺序。

    EX:自定义两个类,实现CommandLineRunner接口,实现run方法,在run方法中添加处理逻辑。

    @Order(5)
    @Component
    public class AppStartReport implements CommandLineRunner {
        @Override
        public void run(String... args) throws Exception {
            System.out.println("AppStartReport : 项目成功启动------------------");
        }
    }
    
    @Order(2)
    @Component
    public class AppStartReport2 implements CommandLineRunner {
        @Override
        public void run(String... args) throws Exception {
            System.out.println("AppStartReport2 : 项目成功启动------------------");
        }
    }
    

    启动效果:AppStartReport2 较AppStartReport 先执行:

    【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口 第1张

    3. ApplicationRunner接口与CommandLineRunner接口的区别

    区别:

    1. CommandLineRunner的方法参数是原始的参数,未做任何处理;
    2. ApplicationRunner的参数为ApplicationArguments对象,是对原始参数的进一步封装。ApplicationArguments是对参数(主要针对main方法)做了进一步的处理,可以解析–name=value的参数,我们就可根据name获取value。
    @Component
    public class AppStartReport3 implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("AppStartReport3 : 项目成功启动,参数为: " + Arrays.asList(args.getSourceArgs()));
        }
    }
    
    @SpringBootApplication
    public class App {
        public static void main(String[] args) {
            SpringApplication application = new SpringApplication(App.class);
            ConfigurableApplicationContext context = application.run("aaa", "bbb");
            context.close();
        }
    }
    

    自行指定参数后,执行效果如下:

    【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口 第2张

    也可以在Program arguments选项框设置初始值,“–key=value“形式,如“–argname=ccc”,如下图所示:

    【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口 第3张

    @SpringBootApplication
    public class App {
        public static void main(String[] args) {
            SpringApplication application = new SpringApplication(App.class);
            ConfigurableApplicationContext context = application.run(args);
            context.close();
        }
    }
    

    启动器传入参数为main方法的参数args,效果如下:

    【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口 第4张

    ApplicationArguments 源码分析

    public interface ApplicationArguments {
       String[] getSourceArgs();
       Set getOptionNames();
       boolean containsOption(String name);
       List getOptionValues(String name);
       List getNonOptionArgs();
    }
    

    资源参数分为两种,一种是在调用run方法时传入的(”aaa”,”bbb”),一种是配置的系统参数即main方法的args参数(”ccc”)。

    • 首先getSourceArgs方法,可以获取到所有参数,可以是自己传入的参数,也可以是配置的系统参数;

    • getNonOptionArgs方法即可获得我们传入的参数(”aaa”,”bbb”)。;

    • 其余3个方法,可获得系统参数。实际用法如下:

      EX:

      @SpringBootApplication
      public class App {
          public static void main(String[] args) {
              SpringApplication application = new SpringApplication(App.class);
              ConfigurableApplicationContext context = application.run(args);
              ApplicationArguments arguments = context.getBean(ApplicationArguments.class);
              System.out.println("参数个数:" + arguments.getSourceArgs().length);
              System.out.println("Non OptionArgs:" + arguments.getNonOptionArgs());
              System.out.println("Option Names:" + arguments.getOptionNames());
              System.out.println("获取key为argname的value值:" + arguments.getOptionValues("argname"));
              System.out.println("是否包含key为argname的参数:" + arguments.containsOption("argname"));
              context.close();
          }
      }
      

      输出效果:

      【SpringBoot】中的ApplicationRunner接口 和 CommandLineRunner接口 第5张

      参考链接:https://blog.csdn.net/qq_35006663/article/details/102264172


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]