SpringBoot之啟動加載器


一、什么是啟動加載器?

在項目啟動的時候做一些初始化工作。

二、啟動類加載器實踐

2.1 實現 CommandLineRunner 接口

@Component
public class FirstCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("run FirstCommandLineRunner");
    }
}

2.2 實現 ApplicationRunner 接口

@Component
public class FirstApplicationRunner implements ApplicationRunner {
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("run FirstApplicationRunner");
    }
}

啟動項目,觀察控制台輸出:

run FirstApplicationRunner
run FirstCommandLineRunner

可以看到默認實現 ApplicationRunner 接口比 CommandLineRunner 優先級高。

2.3 使用 @Order 注解

我們試試看增加 @Order 注解之后會怎么樣

@Component
@Order(1)
public class FirstCommandLineRunner implements CommandLineRunner {
	......
}    
@Component
@Order(2)
public class FirstApplicationRunner implements ApplicationRunner {
    ......
}    

啟動項目,觀察控制台輸出:

run FirstCommandLineRunner
run FirstApplicationRunner

發現 @Order 注解可以改變執行順序。

三、啟動類加載器原理

進入 SpringApplication.run 方法中,callRunners 方法就是入口:

public ConfigurableApplicationContext run(String... args) {
	......
	callRunners(context, applicationArguments);
	......
}

查看 callRunners 方法實現:

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);
    // 循環調用 callRunner 方法
	for (Object runner : new LinkedHashSet<>(runners)) {
		if (runner instanceof ApplicationRunner) {
			callRunner((ApplicationRunner) runner, args);
		}
		if (runner instanceof CommandLineRunner) {
			callRunner((CommandLineRunner) runner, args);
		}
	}
}

可以看到先添加的 ApplicationRunner 接口實現,然后添加 CommandLineRunner 接口實現,所以默認優先級以 ApplicationRunner 為先,后面有個排序實現,以 @Order 進行優先級排序

我們再來分別看下兩個接口各自的 callRunner 的實現:

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);
	}
}	


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM