开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接,netty-socketio服务启动。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为
CommandLineRunner和ApplicationRunner。他们的执行时机为容器启动完成的时候。
使用
这两个接口中有一个run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner中run方法的参数为ApplicationArguments,而CommandLineRunner接口中run方法的参数为String数组。目前我在项目中用的是CommandLineRunner。是这么实现的:
jav@Component
@Slf4j
public class StartRunner implements CommandLineRunner {
@Autowired
SocketIOServer socketIOServer;
@Override
public void run(String... args) throws Exception {
log.info("开始启动socketIOServer");
socketIOServer.start();
log.info("socketIOServer完成");
}
}
在SpringBoot项目启动完成的时候,执行该类的run方法,从而调用执行了SocketIO服务的启动。
执行顺序
run方法的执行顺序是按照顺序执行的,如果我们想要每个要启动的服务按照某种顺序执行,则可以将要先执行的服务写在前面。当然也提供了相关注解的方式,保证CommandLineRunner和ApplicationRunner的实现类按照指定的顺序执行。
其一可以在实现类上加上@Order注解指定执行的顺序;其二可以在实现类上实现Ordered接口来标识。
需要注意:数字越小,优先级越高,也就是@Order(1)注解的类会在@Order(2)注解的类之前执行。
CommandLineRunnerBean1.java
@Component
@Order(1)
public class CommandLineRunnerBean1 implements CommandLineRunner {
public void run(String... args) {
System.out.println("CommandLineRunnerBean 1");
}
}
ApplicationRunnerBean1.java
@Component
@Order(2)
public class ApplicationRunnerBean1 implements ApplicationRunner {
@Override
public void run(ApplicationArguments arg0) throws Exception {
System.out.println("ApplicationRunnerBean 1");
}
}
CommandLineRunnerBean2.java
@Component
@Order(3)
public class CommandLineRunnerBean2 implements CommandLineRunner {
public void run(String... args) {
System.out.println("CommandLineRunnerBean 2");
}
}
ApplicationRunnerBean2.java
@Component
@Order(4)
public class ApplicationRunnerBean2 implements ApplicationRunner {
@Override
public void run(ApplicationArguments arg0) throws Exception {
System.out.println("ApplicationRunnerBean 2");
}
}
输出结果为:
CommandLineRunnerBean 1
ApplicationRunnerBean 1
CommandLineRunnerBean 2
ApplicationRunnerBean 2
总结
通过是用CommandLineRunner和ApplicationRunner我们可以在我们项目启动后自动进行一些初始化工作取配置文件,数据库连接... 由于有些初始化工作是存在先后的执行顺序的,我们可以通过@Order来进行顺序的编排。