我們很多時候在容器啓動時,需要伴隨做一些準備動作,譬如: 讀取配置文件信,數據庫連接,刪除臨時文件,清除緩存信息,而在Spring框架是通過ApplicationListener監聽器來實現的。在Spring Boot中給我們提供了兩個接口來幫助我們實現這樣的需求。這兩個接口就是我們今天要講的CommandLineRunner和ApplicationRunner,他們的執行時機爲容器啓動完成的時候。
簡單的述說一下兩者的不同和相同點:其中不同點有點類似於JS中的(apply與call函數)
共同點:其一執行時機都是在容器啓動完成的時候進行執行;其二這兩個接口中都有一個run()方法;
不同點: ApplicationRunner中run方法的參數爲ApplicationArguments,而CommandLineRunner接口中run方法的參數爲String數組。
官方說明:
- Interface used to indicate that a bean should run when it is contained within
- a SpringApplication. Multiple CommandLineRunner beans can be defined
- within the same application context and can be ordered using the Ordered
- interface or @Order annotation.
- If you need access to ApplicationArguments instead of the raw String array consider using ApplicationRunner.
使用Ordered接口或者Order註解修改執行順序
問題提出: 如果有多個實現類,而我們需要按照一定的順序執行的話,那麼應該怎麼辦呢?
解決方案:其一可以在實現類上加上@Order註解指定執行的順序;其二可以在實現類上實現Ordered接口來標識。
需要注意:數字越小,優先級越高,也就是@Order(1)註解的類會在@Order(2)註解的類之前執行。
示例代碼:
@Component
@Order(66)
@Slf4j
public class InitData implements CommandLineRunner {
@Autowired
private RedisComponent redisComponent;
@Resource
PermissionMapper permissionMapper;
/**
* @param args
* @throws Exception 初始化系統數據
*/
@Override
public void run(String... args) throws Exception {
log.warn("****************初始化數據庫中權限數據**********");
List<PermissionBo> list = permissionMapper.selectAllSystem();
redisComponent.setValue(AuthRdisKeyConst.USYS_SYSTEM_PERMISSION, JSON.toJSONString(list));
log.warn("已加載的權限列表:{}", list);
log.warn("****************數據庫中的權限數據加載完畢*****************");
}
}