摘要:創(chuàng)建及準(zhǔn)備創(chuàng)建。目前已知關(guān)心這個(gè)事件的有要注意的是在這個(gè)階段,里只有,是的加載工作的起點(diǎn)。原因是注入這些回調(diào)接口本身沒(méi)有什么意義。在其構(gòu)造函數(shù)內(nèi)部間接的給注冊(cè)了幾個(gè)與相關(guān)注解的處理器。
相關(guān)代碼在: https://github.com/chanjarster/spring-boot-all-callbacks
注:本文基于spring-boot 1.4.1.RELEASE, spring 4.3.3.RELEASE撰寫(xiě)。
啟動(dòng)順序Spring boot的啟動(dòng)代碼一般是這樣的:
@SpringBootApplication public class SampleApplication { public static void main(String[] args) throws Exception { SpringApplication.run(SampleApplication.class, args); } }初始化SpringApplication
SpringApplication#run(Object source, String... args)#L1174
SpringApplication#L1186 -> SpringApplication(sources)#L236
SpringApplication#initialize(Object[] sources)#L256 javadoc
SpringApplication#L257 添加source(復(fù)數(shù)),SpringApplication使用source來(lái)構(gòu)建Bean。一般來(lái)說(shuō)在run的時(shí)候都會(huì)把@SpringBootApplication標(biāo)記的類(lèi)(本例中是SampleApplication)放到sources參數(shù)里,然后由這個(gè)類(lèi)出發(fā)找到Bean的定義。
SpringApplication#L261 初始化ApplicationContextInitializer列表(見(jiàn)附錄)
SpringApplication#L263 初始化ApplicationListener列表(見(jiàn)附錄)
SpringApplication#L1186 -> SpringApplication#run(args)#L297,進(jìn)入運(yùn)行階段
推送ApplicationStartedEventSpringApplication#run(args)#L297
SpringApplication#L303 初始化SpringApplicationRunListeners (SpringApplicationRunListener的集合)。它內(nèi)部只包含EventPublishingRunListener。
SpringApplication#L304 推送ApplicationStartedEvent給所有的ApplicationListener(見(jiàn)附錄)。 下面是關(guān)心此事件的listener:
LiquibaseServiceLocatorApplicationListener
LoggingApplicationListener(見(jiàn)附錄)
準(zhǔn)備EnvironmentSpringApplication#run(args)#L297->#L308->prepareEnvironment(...)#L331準(zhǔn)備ConfigurableEnvironment。
SpringApplication#L335 創(chuàng)建StandardEnvironment(見(jiàn)附錄)。
SpringApplication#L336 配置StandardEnvironment,將命令行和默認(rèn)參數(shù)整吧整吧,添加到MutablePropertySources。
SpringApplication#L337 推送ApplicationEnvironmentPreparedEvent給所有的ApplicationListener(見(jiàn)附錄)。下面是關(guān)心此事件的listener:
BackgroundPreinitializer
FileEncodingApplicationListener
AnsiOutputApplicationListener
ConfigFileApplicationListener(見(jiàn)附錄)
DelegatingApplicationListener
ClasspathLoggingApplicationListener
LoggingApplicationListener
ApplicationPidFileWriter
可以參考官方文檔了解StandardEnvironment構(gòu)建好之后,其MutablePropertySources內(nèi)部到底有些啥東東。
創(chuàng)建及準(zhǔn)備ApplicationContextSpringApplication#run(args)#L297
SpringApplication#L311->SpringApplication#createApplicationContext()#L583創(chuàng)建ApplicationContext??梢钥吹綄?shí)際上創(chuàng)建的是AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext。
在構(gòu)造AnnotationConfigApplicationContext的時(shí)候,間接注冊(cè)了一個(gè)BeanDefinitionRegistryPostProcessor的Bean:ConfigurationClassPostProcessor。經(jīng)由AnnotatedBeanDefinitionReader構(gòu)造函數(shù)->AnnotationConfigUtils.registerAnnotationConfigProcessors。
SpringApplication#L313->SpringApplication#prepareContext(...)#L344準(zhǔn)備ApplicationContext
SpringApplication#L347->context.setEnvironment(environment),把之前準(zhǔn)備好的Environment塞給ApplicationContext
SpringApplication#L348->postProcessApplicationContext(context)#L605,給ApplicationContext設(shè)置了一些其他東西
SpringApplication#L349->applyInitializers(context)#L630,調(diào)用之前準(zhǔn)備好的ApplicationContextInitializer
SpringApplication#L350->listeners.contextPrepared(context)->EventPublishingRunListener.contextPrepared,但實(shí)際上啥都沒(méi)做。
SpringApplication#L366->load#L687,負(fù)責(zé)將source(復(fù)數(shù))里所定義的Bean加載到ApplicationContext里,在本例中就是SampleApplication,這些source是在初始化SpringApplication階段獲得的。
SpringApplication#L367->listeners.contextLoaded(context)->EventPublishingRunListener.contextLoaded。
將SpringApplication自己擁有的ApplicationListener加入到ApplicationContext
發(fā)送ApplicationPreparedEvent。目前已知關(guān)心這個(gè)事件的有ConfigFileApplicationListener、LoggingApplicationListener、ApplicationPidFileWriter
要注意的是在這個(gè)階段,ApplicationContext里只有SampleApplication,SampleApplication是Bean的加載工作的起點(diǎn)。
刷新ApplicationContext根據(jù)前面所講,這里的ApplicationContext實(shí)際上是GenericApplicationContext
->AnnotationConfigApplicationContext或者AnnotationConfigEmbeddedWebApplicationContext
SpringApplication#run(args)#L297
->#L315->SpringApplication#refreshContext(context)#L370
->#L371->SpringApplication#refresh(context)#L759
->#L761->AbstractApplicationContext#refreshAbstractApplicationContext#L507
AbstractApplicationContext#L510->AbstractApplicationContext#prepareRefresh()#L575,做了一些初始化工作,比如設(shè)置了當(dāng)前Context的狀態(tài),初始化propertySource(其實(shí)啥都沒(méi)干),檢查required的property是否都已在Environment中(其實(shí)并沒(méi)有required的property可供檢查)等。
AbstractApplicationContext#L513->obtainFreshBeanFactory()#L611,獲得BeanFactory,實(shí)際上這里獲得的是DefaultListableBeanFactory
AbstractApplicationContext#L516->prepareBeanFactory(beanFactory)#L625準(zhǔn)備BeanFactory
給beanFactory設(shè)置了ClassLoader
給beanFactory設(shè)置了SpEL解析器
給beanFactory設(shè)置了PropertyEditorRegistrar
給beanFactory添加了ApplicationContextAwareProcessor(BeanPostProcessor的實(shí)現(xiàn)類(lèi)),需要注意的是它是第一個(gè)被添加到BeanFactory的BeanPostProcessor
給beanFactory設(shè)置忽略解析以下類(lèi)的依賴(lài):ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、EnvironmentAware。原因是注入這些回調(diào)接口本身沒(méi)有什么意義。
給beanFactory添加了以下類(lèi)的依賴(lài)解析:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
給beanFactory添加LoadTimeWeaverAwareProcessor用來(lái)處理LoadTimeWeaverAware的回調(diào),在和AspectJ集成的時(shí)候會(huì)用到
把getEnvironment()作為Bean添加到beanFactory中,Bean Name: environment
把getEnvironment().getSystemProperties()作為Bean添加到beanFactory中,Bean Name: systemProperties
把getEnvironment().getSystemEnvironment()作為Bean添加到beanFactory中,Bean Name: systemEnvironment
AbstractApplicationContext#L520->postProcessBeanFactory(beanFactory),后置處理BeanFactory,實(shí)際啥都沒(méi)做
AbstractApplicationContext#L523->invokeBeanFactoryPostProcessors(beanFactory),利用BeanFactoryPostProcessor,對(duì)beanFactory做后置處理。調(diào)用此方法時(shí)有四個(gè)BeanFactoryPostProcessor:
SharedMetadataReaderFactoryContextInitializer的內(nèi)部類(lèi)CachingMetadataReaderFactoryPostProcessor,是在 創(chuàng)建及準(zhǔn)備ApplicationContext 2.3 時(shí)添加的:#L57
ConfigurationWarningsApplicationContextInitializer的內(nèi)部類(lèi)ConfigurationWarningsPostProcessor,是在 創(chuàng)建及準(zhǔn)備ApplicationContext 2.3 時(shí)添加的:#L60
ConfigFileApplicationListener的內(nèi)部類(lèi)PropertySourceOrderingPostProcessor,是在 創(chuàng)建及準(zhǔn)備ApplicationContext 2.6 時(shí)添加的:#L158->#L199->#L244
ConfigurationClassPostProcessor,負(fù)責(zé)讀取BeanDefinition是在 創(chuàng)建及準(zhǔn)備ApplicationContext 1.1 時(shí)添加的
AbstractApplicationContext#L526->registerBeanPostProcessors(beanFactory),注冊(cè)BeanPostProcessor
AbstractApplicationContext#L529->initMessageSource()#L704,初始化MessageSource,不過(guò)其實(shí)此時(shí)的MessageSource是個(gè)Noop對(duì)象。
AbstractApplicationContext#L532->initApplicationEventMulticaster()#L739,初始化ApplicationEventMulticaster。
AbstractApplicationContext#L535->onRefresh()#L793,這個(gè)方法啥都沒(méi)做
AbstractApplicationContext#L538->registerListeners()#L801,把自己的ApplicationListener注冊(cè)到ApplicationEventMulticaster里,并且將之前因?yàn)闆](méi)有ApplicationEventMulticaster而無(wú)法發(fā)出的ApplicationEvent發(fā)送出去。
AbstractApplicationContext#L541->finishBeanFactoryInitialization#L828。注意#L861,在這一步的時(shí)候才會(huì)實(shí)例化所有non-lazy-init bean,這里說(shuō)的實(shí)例化不只是new而已,注入、BeanPostProcessor都會(huì)執(zhí)行。
AbstractApplicationContext#L544->finishRefresh()#L869。
在#L877發(fā)送了ContextRefreshedEvent
調(diào)用 ApplicationRunner 和 CommandLineRunnerSpringApplication#run(args)#L297
->afterRefresh(context, applicationArguments)#L316
->callRunners(context, args)#L771
->#L774 先后調(diào)用了當(dāng)前ApplicationContext中的ApplicationRunner和CommandLineRunner。關(guān)于它們的相關(guān)文檔可以看這里。
需要注意的是,此時(shí)的ApplicationContext已經(jīng)刷新完畢了,該有的Bean都已經(jīng)有了。
推送ApplicationReadyEvent or ApplicationFailedEventSpringApplication#run(args)#L297->listeners.finished(context, null)#L317
間接地調(diào)用了EventPublishingRunListener#getFinishedEventEventPublishingRunListener#L96,發(fā)送了ApplicationReadyEvent或ApplicationFailedEvent
javadoc 相關(guān)文檔
加載方式:讀取classpath*:META-INF/spring.factories中key等于org.springframework.context.ApplicationContextInitializer的property列出的類(lèi)
排序方式:AnnotationAwareOrderComparator
已知清單1:spring-boot-1.4.1.RELEASE.jar!/META-INF/spring.factories
ConfigurationWarningsApplicationContextInitializer(優(yōu)先級(jí):0)
ContextIdApplicationContextInitializer(優(yōu)先級(jí):Ordered.LOWEST_PRECEDENCE - 10)
DelegatingApplicationContextInitializer(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
ServerPortInfoApplicationContextInitializer(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
已知清單2:spring-boot-autoconfigure-1.4.1.RELEASE.jar!/META-INF/spring.factories
SharedMetadataReaderFactoryContextInitializer(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
AutoConfigurationReportLoggingInitializer(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
ApplicationListenerjavadoc 相關(guān)文檔
加載方式:讀取classpath*:META-INF/spring.factories中key等于org.springframework.context.ApplicationListener的property列出的類(lèi)
排序方式:AnnotationAwareOrderComparator
已知清單1:spring-boot-1.4.1.RELEASE.jar!/META-INF/spring.factories中定義的
ClearCachesApplicationListener(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
ParentContextCloserApplicationListener(優(yōu)先級(jí):Ordered.LOWEST_PRECEDENCE - 10)
FileEncodingApplicationListener(優(yōu)先級(jí):Ordered.LOWEST_PRECEDENCE)
AnsiOutputApplicationListener(優(yōu)先級(jí):ConfigFileApplicationListener.DEFAULT_ORDER + 1)
ConfigFileApplicationListener(優(yōu)先級(jí):Ordered.HIGHEST_PRECEDENCE + 10)
DelegatingApplicationListener(優(yōu)先級(jí):0)
LiquibaseServiceLocatorApplicationListener(優(yōu)先級(jí):無(wú)=Ordered.LOWEST_PRECEDENCE)
ClasspathLoggingApplicationListener(優(yōu)先級(jí):LoggingApplicationListener的優(yōu)先級(jí) + 1)
LoggingApplicationListener(優(yōu)先級(jí):Ordered.HIGHEST_PRECEDENCE + 20)
已知清單2:spring-boot-autoconfigure-1.4.1.RELEASE.jar!/META-INF/spring.factories中定義的
BackgroundPreinitializer
SpringApplicationRunListenerjavadoc
加載方式:讀取classpath*:META-INF/spring.factories中key等于org.springframework.boot.SpringApplicationRunListener的property列出的類(lèi)
排序方式:AnnotationAwareOrderComparator
已知清單:spring-boot-1.4.1.RELEASE.jar!/META-INF/spring.factories定義的
org.springframework.boot.context.event.EventPublishingRunListener(優(yōu)先級(jí):0)
EnvironmentPostProcessorEnvironmentPostProcessor可以用來(lái)自定義StandardEnvironment(相關(guān)文檔)。
加載方式:讀取classpath*:META-INF/spring.factories中key等于org.springframework.boot.env.EnvironmentPostProcessor的property列出的類(lèi)
排序方式:AnnotationAwareOrderComparator
已知清單:spring-boot-1.4.1.RELEASE.jar!/META-INF/spring.factories定義的
CloudFoundryVcapEnvironmentPostProcessor(優(yōu)先級(jí):ConfigFileApplicationListener.DEFAULT_ORDER - 1)
SpringApplicationJsonEnvironmentPostProcessor(優(yōu)先級(jí):Ordered.HIGHEST_PRECEDENCE + 5)
BeanPostProcessorjavadoc 相關(guān)文檔
用來(lái)對(duì)Bean實(shí)例進(jìn)行修改的勾子,根據(jù)Javadoc ApplicationContext會(huì)自動(dòng)偵測(cè)到BeanPostProcessor Bean,然后將它們應(yīng)用到后續(xù)創(chuàng)建的所有Bean上。
BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor相關(guān)文檔
PostProcessorRegistrationDelegate負(fù)責(zé)調(diào)用BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor在BeanFactoryPostProcessor之前被調(diào)用。
*Aware是一類(lèi)可以用來(lái)獲得Spring對(duì)象的interface,這些interface都繼承了Aware,已知的有:
ApplicationEventPublisherAware
NotificationPublisherAware
MessageSourceAware
EnvironmentAware
BeanFactoryAware
EmbeddedValueResolverAware
ResourceLoaderAware
ImportAware
LoadTimeWeaverAware
BeanNameAware
BeanClassLoaderAware
ApplicationContextAware
@Configuration 和 Auto-configuration@Configuration替代xml來(lái)定義BeanDefinition的一種手段。Auto-configuration也是定義BeanDefinition的一種手段。
這兩者的相同之處有:
都是使用@Configuration注解的類(lèi),這些類(lèi)里都可以定義@Bean、@Import、@ImportResource。
都可以使用@Condition*來(lái)根據(jù)情況選擇是否加載
而不同之處有:
加載方式不同:
普通@Configuration則是通過(guò)掃描package path加載的
Auto-configuration的是通過(guò)讀取classpath*:META-INF/spring.factories中key等于org.springframework.boot.autoconfigure.EnableAutoConfiguration的property列出的@Configuration加載的
加載順序不同:普通@Configuration的加載永遠(yuǎn)在Auto-configuration之前
內(nèi)部加載順序可控上的不同:
普通@Configuration則無(wú)法控制加載順序
Auto-configuration可以使用@AutoConfigureOrder、@AutoConfigureBefore、@AutoConfigureAfter
以下情況下Auto-configuration會(huì)在普通@Configuration前加載:
Auto-configuration如果出現(xiàn)在最初的掃描路徑里(@ComponentScan),就會(huì)被提前加載到,然后被當(dāng)作普通的@Configuration處理,這樣@AutoConfigureBefore和@AutoConfigureAfter就沒(méi)用了。參看例子代碼里的InsideAutoConfiguration和InsideAutoConfiguration2。
Auto-configuration如果提供BeanPostProcessor,那么它會(huì)被提前加載。參見(jiàn)例子代碼里的BeanPostProcessorAutoConfiguration。
Auto-configuration如果使用了ImportBeanDefinitionRegistrar,那么ImportBeanDefinitionRegistrar會(huì)被提前加載。參見(jiàn)例子代碼里的ImportBeanDefinitionRegistrarAutoConfiguration。
Auto-configuration如果使用了ImportSelector,那么ImportSelector會(huì)被提前加載。參見(jiàn)例子代碼里的UselessDeferredImportSelectorAutoConfiguration。
參考EnableAutoConfiguration和附錄EnableAutoConfigurationImportSelector了解Spring boot內(nèi)部處理機(jī)制
AnnotatedBeanDefinitionReader這個(gè)類(lèi)用來(lái)讀取@Configuration和@Component,并將BeanDefinition注冊(cè)到ApplicationContext里。
ConfigurationClassPostProcessorConfigurationClassPostProcessor是一個(gè)BeanDefinitionRegistryPostProcessor,負(fù)責(zé)處理@Configuration。
需要注意一個(gè)煙霧彈:看#L296->ConfigurationClassUtils#L209。而order的值則是在ConfigurationClassUtils#L122從注解中提取的。
這段代碼似乎告訴我們它會(huì)對(duì)@Configuration進(jìn)行排序,然后按次序加載。
實(shí)際上不是的,@Configuration是一個(gè)遞歸加載的過(guò)程。在本例中,是先從SampleApplication開(kāi)始加載的,而事實(shí)上在這個(gè)時(shí)候,也就只有SampleApplication它自己可以提供排序。
而之后則直接使用了ConfigurationClassParser,它里面并沒(méi)有排序的邏輯。
關(guān)于排序的方式簡(jiǎn)單來(lái)說(shuō)是這樣的:@Configuration的排序根據(jù)且只根據(jù)@Order排序,如果沒(méi)有@Order則優(yōu)先級(jí)最低。
ConfigurationClassParser前面講了ConfigurationClassPostProcessor使用ConfigurationClassParser,實(shí)際上加載@Configuration的工作是在這里做的。
下面講以下加載的順序:
以SampleApplication為起點(diǎn)開(kāi)始掃描
掃描得到所有的@Configuration和@Component,從中讀取BeanDefinition并導(dǎo)入:
如果@Configuration注解了@Import
如果使用的是ImportSelector,則遞歸導(dǎo)入
如果使用的是ImportBeanDefinitionRegistrar,則遞歸導(dǎo)入
如果使用的是DeferredImportSelector,則僅收集不導(dǎo)入
如果@Configuration注解了@ImportResource,則遞歸導(dǎo)入
迭代之前收集的DeferredImportSelector,遞歸導(dǎo)入
那Auto-configuration在哪里呢?
實(shí)際上是在第3步里,@SpringBootApplication存在注解@EnableAutoConfiguration,它使用了EnableAutoConfigurationImportSelector,
EnableAutoConfigurationImportSelector是一個(gè)DeferredImportSelector,所以也就是說(shuō),Auto-configuration是在普通@Configuration之后再加載的。
順帶一提,如果Auto-configuration里再使用DeferredImportSelector,那么效果和使用ImportSelector效果是一樣的,不會(huì)再被延后處理。參見(jiàn)例子代碼里的UselessDeferredImportSelectorAutoConfiguration。
EnableAutoConfigurationImportSelectorEnableAutoConfigurationImportSelector負(fù)責(zé)導(dǎo)入Auto-configuration。
它利用AutoConfigurationSorter對(duì)Auto-configuration進(jìn)行排序。邏輯算法是:
先根據(jù)類(lèi)名排序
再根據(jù)@AutoConfigureOrder排序,如果沒(méi)有@AutoConfigureOrder則優(yōu)先級(jí)最低
再根據(jù)@AutoConfigureBefore,@AutoConfigureAfter排序
內(nèi)置類(lèi)說(shuō)明 LoggingApplicationListenerLoggingApplicationListener用來(lái)配置日志系統(tǒng)的,比如logback、log4j。Spring boot對(duì)于日志有詳細(xì)解釋?zhuān)绻阆胱远x日志配置,那么也請(qǐng)參考本文中對(duì)于LoggingApplicationListener的被調(diào)用時(shí)機(jī)的說(shuō)明以獲得更深入的了解。
StandardEnvironmentStandardEnvironment有一個(gè)MutablePropertySources,它里面有多個(gè)PropertySource,PropertySource負(fù)責(zé)提供property(即property的提供源),目前已知的PropertySource實(shí)現(xiàn)有:MapPropertySource、SystemEnvironmentPropertySource、CommandLinePropertySource等。當(dāng)StandardEnvironment查找property值的時(shí)候,是從MutablePropertySources里依次查找的,而且一旦查找到就不再查找,也就是說(shuō)如果要覆蓋property的值,那么就得提供順序在前的PropertySource。
ConfigFileApplicationListenerConfigFileApplicationListener用來(lái)將application.properties加載到StandardEnvironment中。
ConfigFileApplicationListener內(nèi)部使用了EnvironmentPostProcessor(見(jiàn)附錄)自定義StandardEnvironment
ApplicationContextAwareProcessorApplicationContextAwareProcessor實(shí)現(xiàn)了BeanPostProcessor接口,根據(jù)javadoc這個(gè)類(lèi)用來(lái)調(diào)用以下接口的回調(diào)方法:
EnvironmentAware
EmbeddedValueResolverAware
ResourceLoaderAware
ApplicationEventPublisherAware
MessageSourceAware
ApplicationContextAware
AnnotationConfigApplicationContext根據(jù)javadoc,這個(gè)類(lèi)用來(lái)將@Configuration和@Component作為輸入來(lái)注冊(cè)BeanDefinition。
特別需要注意的是,在javadoc中講到其支持@Bean的覆蓋:
In case of multiple @Configuration classes, @Bean methods defined in later classes will override those defined in earlier classes. This can be leveraged to deliberately override certain bean definitions via an extra @Configuration class.
它使用AnnotatedBeanDefinitionReader來(lái)讀取@Configuration和@Component。
AnnotatedBeanDefinitionReaderAnnotatedBeanDefinitionReader在其構(gòu)造函數(shù)內(nèi)部間接(AnnotationConfigUtils#L145)的給BeanFactory注冊(cè)了幾個(gè)與BeanDefinition相關(guān)注解的處理器。
ConfigurationClassPostProcessor
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
EventListenerMethodProcessor
PersistenceAnnotationBeanPostProcessor
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/66039.html
摘要:在一個(gè)初春的下午,甲跟我說(shuō),要在啟動(dòng)服務(wù)的時(shí)候,設(shè)置表自增的起始值。寫(xiě)完啟動(dòng)項(xiàng),那么再把退出也說(shuō)一下每一個(gè)都應(yīng)該向注冊(cè)一個(gè)鉤子函數(shù)來(lái)確保能優(yōu)雅地關(guān)閉。后面退出部分翻譯地磕磕碰碰的,有不對(duì)的地方歡迎指正。原創(chuàng)不易,感謝支持。 在一個(gè)初春的下午,甲跟我說(shuō),要在Spring Boot啟動(dòng)服務(wù)的時(shí)候,設(shè)置表自增的起始值。于是我用屁股想了一下,不就是在main方法里折騰嘛。后來(lái)實(shí)際操作了一把,發(fā)...
摘要:代碼示例本文示例讀者可以通過(guò)查看下面?zhèn)}庫(kù)的中的三個(gè)項(xiàng)目如果您對(duì)這些感興趣,歡迎收藏轉(zhuǎn)發(fā)給予支持以下專(zhuān)題教程也許您會(huì)有興趣基礎(chǔ)教程基礎(chǔ)教程 有很多讀者問(wèn)過(guò)這樣的一個(gè)問(wèn)題:雖然使用Swagger可以為Spring MVC編寫(xiě)的接口生成了API文檔,但是在微服務(wù)化之后,這些API文檔都離散在各個(gè)微服務(wù)中,是否有辦法將這些接口都整合到一個(gè)文檔中?之前給大家的回復(fù)都只是簡(jiǎn)單的說(shuō)了個(gè)思路,昨天正好...
摘要:總結(jié)基于構(gòu)建相對(duì)來(lái)說(shuō)還是比較便捷的,其中注解使得代碼更加簡(jiǎn)潔,本次用到注解再匯總下,有時(shí)間的話可以深入理解下其背后的原理申明讓自動(dòng)給程序進(jìn)行必要的配置。風(fēng)格的控制器提供路由信息,負(fù)責(zé)到中的具體函數(shù)的映射一般用于修飾層的組件自動(dòng)導(dǎo)入依賴(lài)的 本文主要記錄搭建RESTful API標(biāo)準(zhǔn)工程,包含比較推薦的工程結(jié)構(gòu),掌握一些基本注解,并引入Swagger 新建一個(gè)項(xiàng)目 通過(guò)Spring Ini...
摘要:實(shí)例定義一個(gè)實(shí)現(xiàn),并納入到容器中進(jìn)行處理啟動(dòng)定義一個(gè)實(shí)現(xiàn),并納入到容器處理應(yīng)用已經(jīng)成功啟動(dòng)啟動(dòng)類(lèi)測(cè)試,也可以直接在容器訪問(wèn)該值,配置參數(shù),然后執(zhí)行啟動(dòng)類(lèi)打印結(jié)果接口發(fā)現(xiàn)二者的官方一樣,區(qū)別在于接收的參數(shù)不一樣。引言 我們?cè)谑褂肧pringBoot搭建項(xiàng)目的時(shí)候,如果希望在項(xiàng)目啟動(dòng)完成之前,能夠初始化一些操作,針對(duì)這種需求,可以考慮實(shí)現(xiàn)如下兩個(gè)接口(任一個(gè)都可以) org.springfram...
摘要:除了,還有十余種,有的是特定操作,比如轉(zhuǎn)儲(chǔ)內(nèi)存日志有的是信息展示,比如顯示應(yīng)用健康狀態(tài)。 showImg(http://ww1.sinaimg.cn/large/006tNc79gy1g5qb2coyfoj30u00k0tan.jpg); 前言 隨著線上應(yīng)用逐步采用 SpringBoot 構(gòu)建,SpringBoot應(yīng)用實(shí)例越來(lái)多,當(dāng)線上某個(gè)應(yīng)用需要升級(jí)部署時(shí),常常簡(jiǎn)單粗暴地使用 kil...
閱讀 3965·2021-09-09 09:33
閱讀 1830·2021-09-06 15:14
閱讀 1955·2019-08-30 15:44
閱讀 3128·2019-08-29 18:36
閱讀 3798·2019-08-29 16:22
閱讀 2122·2019-08-29 16:21
閱讀 2572·2019-08-29 15:42
閱讀 1678·2019-08-29 11:00