开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第31天,点击查看活动详情
有时候我们需要在容器启动的时候执行一些内容,SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为 CommandLineRunner和 ApplicationRunner。他们的执行时机为容器启动完成的时候。,比如:读取配置文件,数据库连接之类,加载一些系统参数,完成初始化,预热本地缓存等。
springboot两个接口类:
- CommandLineRunner
- ApplicationRunner
这两个接口中有一个 run方法,我们只需要实现这个方法即可。这两个接口的不同之处在于:ApplicationRunner中 run方法的参数为 ApplicationArguments,而CommandLineRunner接口中 run方法的参数为 String数组。
1、ApplicationRunner实现
ApplicationRunner的执行时机为容器启动完成的时候。
ApplicationRunner类:
@Component
public class TestRunner implements ApplicationRunner {
@Autowired
private LoadDataService loadDataService;
public void run(ApplicationArguments args) throws Exception {
loadDataService.load();
}
}
实现ApplicationRunner
接口,重写run
方法,在该方法中实现自己定制化需求。
如果项目中有多个类实现了ApplicationRunner接口,他们的执行顺序要怎么指定呢?
答案是使用@Order(n)
注解,n的值越小越先执行。当然也可以通过@Priority
注解指定顺序。
2、CommandLineRunner实现
同样,CommandLineRunner实的执行时机为容器启动完成的时候。
@Component
@Order(1)
public class Runner1 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("step 3: The Runner1 run...");
}
}
@Component
@Order(2)
public class Runner2 implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("step 4: The Runner1 run...");
}
}
3、@PostConstruct注解
如果想在某个对象生成时候完成某些初始化操作,而偏偏这些初始化操作又依赖于依赖注入的对象,那么就无法在构造函数中实现:@PostConstruct注解的方法会将在依赖注入完成之后被自动调用。该注解在整个Bean初始化中执行的顺序:@Constructor(构造方法)->@Autowired(依赖注入)->@PostConstruct(注解的方法)。
例如:定义一个UserController类,在依赖注入完成后做一些操作。
public class UserController {
@Autowired
private UserService userService;
// 初始化方法
@PostConstruct
public void init(){
userService.userServiceInit();
}
}
@PostConstruct注解来完成初始化,@PostConstruct注解的方法将会在UserService注入完成后被自动调用。
当然也可以使用实现InitializingBean接口,实现InitializingBean接口重写afterPropertiesSet方法做一些初始化操作。比较常见的如SqlSessionFactoryBean,它就是通过实现InitializingBean完成初始化的。
@Override
public void afterPropertiesSet() throws Exception {
// buildSqlSessionFactory()是完成初始化的核心方法,必须在构造方法调用后执行
this.sqlSessionFactory = buildSqlSessionFactory();
}