ApplicationRunner/CommandLineRunner:容器启动后回调,执行一些初始化工作

114 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 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(); 
}