spring解决方案

需求

springboot项目启动完成执行指定方法

方案一可以通过SpringApplicationRunListener实现

方案二(推荐)

org.springframework.boot.ApplicationRunner
org.springframework.boot.CommandLineRunner
这两个接口是springBoot提供用来在spring容器加载完成后执行指定方法;
测试类:


@Slf4j
@Component
public class RunnerTest implements ApplicationRunner, CommandLineRunner {

  @Override
  public void run(ApplicationArguments args) throws Exception {
    System.out.println("服务启动RunnerTest   ApplicationRunner执行启动加载任务...");
    String[] sourceArgs = args.getSourceArgs();
    if (null != sourceArgs) {
      for (String s : sourceArgs) {
        System.out.println(s);
      }
    }
    System.out.println("服务启动RunnerTest   ApplicationRunner执行启动加载任务...option参数...");
    Set<String> optionNames = args.getOptionNames();
    for (String s : optionNames) {
      System.out.println(s + "" + JSONObject.toJSONString(args.getOptionValues(s)));
    }

  }

  @Override
  public void run(String... args) throws Exception {
    System.out.println("服务启动RunnerTest    CommandLineRunner 执行启动加载任务...");
    if (null != args) {
      for (String s : args) {
        System.out.println(s);
      }
    }
  }
}

执行结果:
在这里插入图片描述

结果

通过执行结果可以看到,这两个接口都在springboot启动完成后执行的
ApplicationRunner接口的方法先执行,CommandLineRunner后执行;

区别

这两个方法的区别就是接口参数不同,CommandLineRunner传的就是main方法里面数组,而ApplicationRunner传的参数则进行了封装,ApplicationArguments封装成这个参数了.

idea设置参数

输入参数如下:
参数以空格分隔,–- 开头的参数会被解析成Option类型的参数;

test fsaf aaa vvv --mygroub=a,b --filePath=c:/aa --mygroub=cd

在这里插入图片描述

在这里插入图片描述

源码解析执行时机

首先看 SpringApplication.run()的方法:
在这里插入图片描述

我们直接看执行Runners的地方:
就是重容器中获取ApplicationRunner,CommandLineRunner,然后遍历进行执行方法,CommandLineRunner执行也是从ApplicationArguments参数中获取args:

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


	private void callRunner(ApplicationRunner runner, ApplicationArguments args) {
		try {
			(runner).run(args);
		}
		catch (Exception ex) {
			throw new IllegalStateException("Failed to execute ApplicationRunner", ex);
		}
	}

	private void callRunner(CommandLineRunner runner, ApplicationArguments args) {
		try {
			(runner).run(args.getSourceArgs());
		}
		catch (Exception ex) {
			throw new IllegalStateException("Failed to execute CommandLineRunner", ex);
		}
	}


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐