<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
SpringBoot在2.4版本以後預設不載入bootstrap.yml設定項。
如果需要載入該設定項,需要引入依賴,通常Spring Cloud工程配合nacos這種設定中心或註冊中心使用時,需要引入該依賴。
SpringBoot單體工程無需引入該依賴,所有設定放在application.yml中即可。
<!-- bootstrap 啟動器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency>
SpringBoot工程在啟動時,會通過SpringFactoriesLoader檢索META-INF/spring.factories檔案,並載入其中的設定項。
常見的設定項有如下幾種:
建構函式:初始化web容器,載入ApplicationContextInitializer的實現類並將其範例化,載入ApplicationListener的實現類並將其範例化
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { this.resourceLoader = resourceLoader; Assert.notNull(primarySources, "PrimarySources must not be null"); this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); // 初始化web容器型別,預設SERVLET,如果存在org.springframework.web.reactive.DispatcherHandler,則是REACTIVE this.webApplicationType = WebApplicationType.deduceFromClasspath(); this.bootstrapRegistryInitializers = new ArrayList<>( getSpringFactoriesInstances(BootstrapRegistryInitializer.class)); //找到*META-INF/spring.factories*中宣告的所有ApplicationContextInitializer的實現類並將其範例化 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); //找到*META-INF/spring.factories*中宣告的所有ApplicationListener的實現類並將其範例化 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); //獲得當前執行main方法的類物件 this.mainApplicationClass = deduceMainApplicationClass(); }
啟動方法
public ConfigurableApplicationContext run(String... args) { long startTime = System.nanoTime(); // 建立bootstrap上下文 DefaultBootstrapContext bootstrapContext = createBootstrapContext(); ConfigurableApplicationContext context = null; configureHeadlessProperty(); //通過*SpringFactoriesLoader*檢索*META-INF/spring.factories*, //找到宣告的所有SpringApplicationRunListener的實現類並將其範例化, //之後逐個呼叫其started()方法,廣播SpringBoot要開始執行了。 SpringApplicationRunListeners listeners = getRunListeners(args); listeners.starting(bootstrapContext, this.mainApplicationClass); try { ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //建立並設定當前SpringBoot應用將要使用的Environment(包括設定要使用的PropertySource以及Profile), //並遍歷呼叫所有的SpringApplicationRunListener的environmentPrepared()方法,廣播Environment準備完畢。 ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); //決定是否列印Banner configureIgnoreBeanInfo(environment); Banner printedBanner = printBanner(environment); //根據webApplicationType的值來決定建立何種型別的ApplicationContext物件 //如果是SERVLET環境,則建立AnnotationConfigServletWebServerApplicationContext //如果是REACTIVE環境,則建立AnnotationConfigReactiveWebServerApplicationContext //否則建立AnnotationConfigApplicationContext context = createApplicationContext(); context.setApplicationStartup(this.applicationStartup); //為ApplicationContext載入environment,之後逐個執行ApplicationContextInitializer的initialize()方法來進一步封裝ApplicationContext, //並呼叫所有的SpringApplicationRunListener的contextPrepared()方法,【EventPublishingRunListener只提供了一個空的contextPrepared()方法】, //之後初始化IoC容器,並呼叫SpringApplicationRunListener的contextLoaded()方法,廣播ApplicationContext的IoC載入完成, //這裡就包括通過**@EnableAutoConfiguration**匯入的各種自動設定類。 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); //初始化所有自動設定類,呼叫ApplicationContext的refresh()方法 refreshContext(context); //目前該方法為空 afterRefresh(context, applicationArguments); Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup); } //呼叫所有的SpringApplicationRunListener的started()方法,廣播SpringBoot已經完成了ApplicationContext初始化的全部過程。 listeners.started(context, timeTakenToStartup); //遍歷所有註冊的ApplicationRunner和CommandLineRunner,並執行其run()方法。 //該過程可以理解為是SpringBoot完成ApplicationContext初始化前的最後一步工作, //我們可以實現自己的ApplicationRunner或者CommandLineRunner,來對SpringBoot的啟動過程進行擴充套件。 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, listeners); throw new IllegalStateException(ex); } try { Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime); listeners.ready(context, timeTakenToReady); } catch (Throwable ex) { handleRunFailure(context, ex, null); throw new IllegalStateException(ex); } return context; }
我們的程式經常需要在啟動過程中或啟動完成後做一些額外的邏輯處理,那麼可以通過以下三種方式處理:
1)建立實現類
public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void initialize(ConfigurableApplicationContext applicationContext) { logger.info("MyApplicationContextInitializer, {}", applicationContext.getApplicationName()); } }
2)設定META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer= com.hsoft.demo.MyApplicationContextInitializer
3)或者修改啟動方法,呼叫addInitializers新增
public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addInitializers(new MyApplicationContextInitializer()); springApplication.run(args); }
ApplicationListener也有兩種方式,首先建立實現類,然後修改啟動方法,呼叫addListeners
新增,或者直接新增註解@Component
@Component public class MyApplicationListener implements ApplicationListener<ApplicationReadyEvent> { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void onApplicationEvent(ApplicationReadyEvent event) { logger.info("MyApplicationListener,{}",event.toString()); } }
public static void main(String[] args) { SpringApplication springApplication = new SpringApplication(Application.class); springApplication.addListeners(new MyApplicationListener()); springApplication.run(args); }
也可以通過設定META-INF/spring.factories實現
# Application Listeners
org.springframework.context.ApplicationListener=
com.hsoft.demo.MyApplicationListener
推薦直接使用註解@Component
或addListeners()
方式,如果設定META-INF/spring.factories,因bootstrap設定分開載入所以監聽程式會被觸發兩次
只需建立一個實現型別,並在實現類上面增加註解@Component即可
@Component public class MyApplicationRunner implements ApplicationRunner { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void run(ApplicationArguments args) throws Exception { logger.info("MyApplicationRunner, {}",args.getOptionNames()); } }
@Component public class MyCommandLineRunner implements CommandLineRunner { private final Logger logger = LoggerFactory.getLogger(getClass()); @Override public void run(String... args) throws Exception { logger.info("MyCommandLineRunner, {}", args); } }
如果SpringBoot工程要在Tomcat中部署,需要通過如下操作:
1、修改成war工程
2、嵌入式Tomcat依賴scope指定provided
3、編寫SpringBootServletInitializer類子類,並重寫configure方法
/** * web容器中進行部署 * */ public class MyServletInitializer extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(MyApplication.class); } }
到此這篇關於SpringBoot工程啟動順序與自定義監聽超詳細講解的文章就介紹到這了,更多相關SpringBoot工程啟動順序內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45