国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - spring boot容器啟動流程

spring boot容器啟動流程

2021-03-26 11:20只會一點java Java教程

spring cloud是基于spring boot快速搭建的,今天咱們就看看spring boot容器啟動流程,需要的朋友跟隨腳本之家小編一起學習吧

一、前言

spring cloud大行其道的當下,如果不了解基本原理那么是很糾結的(看見的都是 約定大于配置 ,但是原理呢?為什么要這么做?)。spring cloud是基于spring boot快速搭建的,今天咱們就看看spring boot容器啟動流程。(本文不講解如何快速啟動spring boot,那些直接官方看即可, 官網文檔飛機票 )

二、容器啟動

spring boot一般是 指定容器啟動main方法,然后以命令行方式啟動jar包 ,如下圖:

?
1
2
3
4
5
6
@springbootapplication
public class application {
 public static void main(string[] args) {
 springapplication.run(application.class, args);
 }
 }

這里核心關注2個東西:

1.@springbootapplication注解

2. springapplication.run()靜態方法

下面我們就分別探究這兩塊內容。

2.1 @springbootapplication注解

源碼如下:  

?
1
2
3
4
5
6
7
8
9
10
@target(elementtype.type)
@retention(retentionpolicy.runtime)
@documented
@inherited
@springbootconfiguration
@enableautoconfiguration
@componentscan(excludefilters = {
@filter(type = filtertype.custom, classes = typeexcludefilter.class),
@filter(type = filtertype.custom, classes = autoconfigurationexcludefilter.class) })
public @interface springbootapplication {

核心注解:

@springbootconfiguration(實際就是個@configuration):表示這是一個javaconfig配置類,可以在這個類中自定義bean,依賴關系等。-》這個是spring-boot特有的注解,常用到。

@enableautoconfiguration:借助@import的幫助,將所有符合自動配置條件的bean定義加載到ioc容器(建議放在根包路徑下,這樣可以掃描子包和類)。-》這個需要詳細深挖!

@componentscan:spring的自動掃描注解,可定義掃描范圍,加載到ioc容器。-》這個不多說,spring的注解大家肯定眼熟

其中@enableautoconfiguration這個注解的源碼:

?
1
2
3
4
5
6
7
8
@suppresswarnings("deprecation")
@target(elementtype.type)
@retention(retentionpolicy.runtime)
@documented
@inherited
@autoconfigurationpackage
@import(enableautoconfigurationimportselector.class)
public @interface enableautoconfiguration {

核心是一個enableautoconfigurationimportselector類圖如下:

 spring boot容器啟動流程

核心方法在頂級接口 importselector 的 selectimports() ,源碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@override
public string[] selectimports(annotationmetadata annotationmetadata) {
if (!isenabled(annotationmetadata)) {
return no_imports;
}
try { //1.從meta-inf/spring-autoconfigure-metadata.properties文件中載入483條配置屬性(有一些有默認值),
autoconfigurationmetadata autoconfigurationmetadata = autoconfigurationmetadataloader
 .loadmetadata(this.beanclassloader);
annotationattributes attributes = getattributes(annotationmetadata);//2.獲取注解屬性
list<string> configurations = getcandidateconfigurations(annotationmetadata,//3.獲取97個自動配置類
 attributes);
configurations = removeduplicates(configurations);//4.移除重復的
configurations = sort(configurations, autoconfigurationmetadata);//5.排序
set<string> exclusions = getexclusions(annotationmetadata, attributes);//6.獲取需要排除的
checkexcludedclasses(configurations, exclusions);//7.校驗排除類
configurations.removeall(exclusions);//8.刪除所有需要排除的
configurations = filter(configurations, autoconfigurationmetadata);//9.過濾器onclasscondition(注解中配置的當存在某類才生效)
fireautoconfigurationimportevents(configurations, exclusions);//10.觸發自動配置導入監聽事件
return configurations.toarray(new string[configurations.size()]);
}
catch (ioexception ex) {
throw new illegalstateexception(ex);
}
}

這里注意3個核心方法:

1) loadmetadata 加載配置

其實就是用類加載器去加載: meta-inf/spring-autoconfigure-metadata.properties (spring-boot-autoconfigure-1.5.9.release-sources.jar) 文件中定義的配置,返回propertiesautoconfigurationmetadata(實現了autoconfigurationmetadata接口,封裝了屬性的get set方法)

2) getcandidateconfigurations 獲取默認支持的自動配置類名列表

自動配置靈魂方法, springfactoriesloader.loadfactorynames 從 meta-inf/spring.factories (spring-boot-autoconfigure-1.5.9.release-sources.jar)文件中獲取自動配置類key=enableautoconfiguration.class的配置。 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
protected list<string> getcandidateconfigurations(annotationmetadata metadata,
 annotationattributes attributes) {//話說這里2個入參沒啥用啊...誰來給我解釋一下...
 list<string> configurations = springfactoriesloader.loadfactorynames(
  getspringfactoriesloaderfactoryclass(), getbeanclassloader());
 assert.notempty(configurations,
  "no auto configuration classes found in meta-inf/spring.factories. if you "
  + "are using a custom packaging, make sure that file is correct.");
 return configurations;
 }
 //返回的是enableautoconfiguration類
 protected class<?> getspringfactoriesloaderfactoryclass() {
 return enableautoconfiguration.class;
 }

實際獲取了什么? spring.factories 文件如下,實際獲取了 # auto configure 自動配置模塊的所有類。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# initializers
org.springframework.context.applicationcontextinitializer=\
org.springframework.boot.autoconfigure.sharedmetadatareaderfactorycontextinitializer,\
org.springframework.boot.autoconfigure.logging.autoconfigurationreportlogginginitializer
# application listeners
org.springframework.context.applicationlistener=\
org.springframework.boot.autoconfigure.backgroundpreinitializer
# auto configuration import listeners
org.springframework.boot.autoconfigure.autoconfigurationimportlistener=\
org.springframework.boot.autoconfigure.condition.conditionevaluationreportautoconfigurationimportlistener
# auto configuration import filters
org.springframework.boot.autoconfigure.autoconfigurationimportfilter=\
org.springframework.boot.autoconfigure.condition.onclasscondition
# auto configure 這里就是全部的自動配置類
org.springframework.boot.autoconfigure.enableautoconfiguration=\
org.springframework.boot.autoconfigure.admin.springapplicationadminjmxautoconfiguration,\
org.springframework.boot.autoconfigure.aop.aopautoconfiguration,\
org.springframework.boot.autoconfigure.amqp.rabbitautoconfiguration,\
org.springframework.boot.autoconfigure.batch.batchautoconfiguration,\
org.springframework.boot.autoconfigure.cache.cacheautoconfiguration,\
org.springframework.boot.autoconfigure.cassandra.cassandraautoconfiguration,\
org.springframework.boot.autoconfigure.cloud.cloudautoconfiguration,\
org.springframework.boot.autoconfigure.context.configurationpropertiesautoconfiguration,\
org.springframework.boot.autoconfigure.context.messagesourceautoconfiguration,\
org.springframework.boot.autoconfigure.context.propertyplaceholderautoconfiguration,\
org.springframework.boot.autoconfigure.couchbase.couchbaseautoconfiguration,\
org.springframework.boot.autoconfigure.dao.persistenceexceptiontranslationautoconfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.cassandradataautoconfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.cassandrarepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.couchbasedataautoconfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.couchbaserepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.jpa.jparepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.ldap.ldapdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.ldap.ldaprepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.mongo.mongodataautoconfiguration,\
org.springframework.boot.autoconfigure.data.mongo.mongorepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.neo4jdataautoconfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.neo4jrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.solr.solrrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.redis.redisautoconfiguration,\
org.springframework.boot.autoconfigure.data.redis.redisrepositoriesautoconfiguration,\
org.springframework.boot.autoconfigure.data.rest.repositoryrestmvcautoconfiguration,\
org.springframework.boot.autoconfigure.data.web.springdatawebautoconfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.jestautoconfiguration,\
org.springframework.boot.autoconfigure.freemarker.freemarkerautoconfiguration,\
org.springframework.boot.autoconfigure.gson.gsonautoconfiguration,\
org.springframework.boot.autoconfigure.h2.h2consoleautoconfiguration,\
org.springframework.boot.autoconfigure.hateoas.hypermediaautoconfiguration,\
org.springframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,\
org.springframework.boot.autoconfigure.hazelcast.hazelcastjpadependencyautoconfiguration,\
org.springframework.boot.autoconfigure.info.projectinfoautoconfiguration,\
org.springframework.boot.autoconfigure.integration.integrationautoconfiguration,\
org.springframework.boot.autoconfigure.jackson.jacksonautoconfiguration,\
org.springframework.boot.autoconfigure.jdbc.datasourceautoconfiguration,\
org.springframework.boot.autoconfigure.jdbc.jdbctemplateautoconfiguration,\
org.springframework.boot.autoconfigure.jdbc.jndidatasourceautoconfiguration,\
org.springframework.boot.autoconfigure.jdbc.xadatasourceautoconfiguration,\
org.springframework.boot.autoconfigure.jdbc.datasourcetransactionmanagerautoconfiguration,\
org.springframework.boot.autoconfigure.jms.jmsautoconfiguration,\
org.springframework.boot.autoconfigure.jmx.jmxautoconfiguration,\
org.springframework.boot.autoconfigure.jms.jndiconnectionfactoryautoconfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.activemqautoconfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.artemisautoconfiguration,\
org.springframework.boot.autoconfigure.flyway.flywayautoconfiguration,\
org.springframework.boot.autoconfigure.groovy.template.groovytemplateautoconfiguration,\
org.springframework.boot.autoconfigure.jersey.jerseyautoconfiguration,\
org.springframework.boot.autoconfigure.jooq.jooqautoconfiguration,\
org.springframework.boot.autoconfigure.kafka.kafkaautoconfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.embeddedldapautoconfiguration,\
org.springframework.boot.autoconfigure.ldap.ldapautoconfiguration,\
org.springframework.boot.autoconfigure.liquibase.liquibaseautoconfiguration,\
org.springframework.boot.autoconfigure.mail.mailsenderautoconfiguration,\
org.springframework.boot.autoconfigure.mail.mailsendervalidatorautoconfiguration,\
org.springframework.boot.autoconfigure.mobile.deviceresolverautoconfiguration,\
org.springframework.boot.autoconfigure.mobile.devicedelegatingviewresolverautoconfiguration,\
org.springframework.boot.autoconfigure.mobile.sitepreferenceautoconfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.embeddedmongoautoconfiguration,\
org.springframework.boot.autoconfigure.mongo.mongoautoconfiguration,\
org.springframework.boot.autoconfigure.mustache.mustacheautoconfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.hibernatejpaautoconfiguration,\
org.springframework.boot.autoconfigure.reactor.reactorautoconfiguration,\
org.springframework.boot.autoconfigure.security.securityautoconfiguration,\
org.springframework.boot.autoconfigure.security.securityfilterautoconfiguration,\
org.springframework.boot.autoconfigure.security.fallbackwebsecurityautoconfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.oauth2autoconfiguration,\
org.springframework.boot.autoconfigure.sendgrid.sendgridautoconfiguration,\
org.springframework.boot.autoconfigure.session.sessionautoconfiguration,\
org.springframework.boot.autoconfigure.social.socialwebautoconfiguration,\
org.springframework.boot.autoconfigure.social.facebookautoconfiguration,\
org.springframework.boot.autoconfigure.social.linkedinautoconfiguration,\
org.springframework.boot.autoconfigure.social.twitterautoconfiguration,\
org.springframework.boot.autoconfigure.solr.solrautoconfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.thymeleafautoconfiguration,\
org.springframework.boot.autoconfigure.transaction.transactionautoconfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.jtaautoconfiguration,\
org.springframework.boot.autoconfigure.validation.validationautoconfiguration,\
org.springframework.boot.autoconfigure.web.dispatcherservletautoconfiguration,\
org.springframework.boot.autoconfigure.web.embeddedservletcontainerautoconfiguration,\
org.springframework.boot.autoconfigure.web.errormvcautoconfiguration,\
org.springframework.boot.autoconfigure.web.httpencodingautoconfiguration,\
org.springframework.boot.autoconfigure.web.httpmessageconvertersautoconfiguration,\
org.springframework.boot.autoconfigure.web.multipartautoconfiguration,\
org.springframework.boot.autoconfigure.web.serverpropertiesautoconfiguration,\
org.springframework.boot.autoconfigure.web.webclientautoconfiguration,\
org.springframework.boot.autoconfigure.web.webmvcautoconfiguration,\
org.springframework.boot.autoconfigure.websocket.websocketautoconfiguration,\
org.springframework.boot.autoconfigure.websocket.websocketmessagingautoconfiguration,\
org.springframework.boot.autoconfigure.webservices.webservicesautoconfiguration
# failure analyzers
org.springframework.boot.diagnostics.failureanalyzer=\
org.springframework.boot.autoconfigure.diagnostics.analyzer.nosuchbeandefinitionfailureanalyzer,\
org.springframework.boot.autoconfigure.jdbc.datasourcebeancreationfailureanalyzer,\
org.springframework.boot.autoconfigure.jdbc.hikaridriverconfigurationfailureanalyzer
# template availability providers
org.springframework.boot.autoconfigure.template.templateavailabilityprovider=\
org.springframework.boot.autoconfigure.freemarker.freemarkertemplateavailabilityprovider,\
org.springframework.boot.autoconfigure.mustache.mustachetemplateavailabilityprovider,\
org.springframework.boot.autoconfigure.groovy.template.groovytemplateavailabilityprovider,\
org.springframework.boot.autoconfigure.thymeleaf.thymeleaftemplateavailabilityprovider,\
org.springframework.boot.autoconfigure.web.jsptemplateavailabilityprovider

3)filter過濾器 根據 onclasscondition 注解把不滿足條件的過濾掉

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private list<string> filter(list<string> configurations,
autoconfigurationmetadata autoconfigurationmetadata) {
long starttime = system.nanotime();
string[] candidates = configurations.toarray(new string[configurations.size()]);
boolean[] skip = new boolean[candidates.length];
boolean skipped = false;
//獲取需要過濾的自動配置導入攔截器,spring.factories配置中就一個:org.springframework.boot.autoconfigure.condition.onclasscondition
for (autoconfigurationimportfilter filter : getautoconfigurationimportfilters()) {
invokeawaremethods(filter);
boolean[] match = filter.match(candidates, autoconfigurationmetadata);
for (int i = 0; i < match.length; i++) {
 if (!match[i]) {
 skip[i] = true;
 skipped = true;
 }
}
}
if (!skipped) {//多條件只要有一個不匹配->skipped = true,全部匹配-》skipped = false->直接返回
return configurations;
}
list<string> result = new arraylist<string>(candidates.length);
for (int i = 0; i < candidates.length; i++) {
if (!skip[i]) {//匹配-》不跳過-》添加進result
 result.add(candidates[i]);
}
}
if (logger.istraceenabled()) {
int numberfiltered = configurations.size() - result.size();
logger.trace("filtered " + numberfiltered + " auto configuration class in "
 + timeunit.nanoseconds.tomillis(system.nanotime() - starttime)
 + " ms");
}
return new arraylist<string>(result);
}

2.2 springapplication .run()靜態方法

springapplication.run 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public configurableapplicationcontext run(string... args) {
stopwatch stopwatch = new stopwatch();
stopwatch.start();
configurableapplicationcontext context = null;
failureanalyzers analyzers = null;
configureheadlessproperty();
springapplicationrunlisteners listeners = getrunlisteners(args);//1.獲取監聽器
listeners.starting();-->啟動!
try {
applicationarguments applicationarguments = new defaultapplicationarguments(
 args);
configurableenvironment environment = prepareenvironment(listeners,//2.準備好環境,觸發applicationenvironmentpreparedevent事件
 applicationarguments);
banner printedbanner = printbanner(environment);//打印啟動提示字符,默認spring的字符圖
context = createapplicationcontext();//實例化一個可配置應用上下文
analyzers = new failureanalyzers(context);
preparecontext(context, environment, listeners, applicationarguments,//3.準備上下文
 printedbanner);
refreshcontext(context);//4.刷新上下文
afterrefresh(context, applicationarguments);//5.刷新上下文后
listeners.finished(context, null);--關閉!
stopwatch.stop();
if (this.logstartupinfo) {
 new startupinfologger(this.mainapplicationclass)
 .logstarted(getapplicationlog(), stopwatch);
}
return context;
}
catch (throwable ex) {
handlerunfailure(context, listeners, analyzers, ex);
throw new illegalstateexception(ex);
}
}

1. getrunlisteners 獲取監聽器( springapplicationrunlisteners )

實際是 springapplicationrunlistener 類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private springapplicationrunlisteners getrunlisteners(string[] args) {
class<?>[] types = new class<?>[] { springapplication.class, string[].class };
return new springapplicationrunlisteners(logger, getspringfactoriesinstances(
springapplicationrunlistener.class, types, this, args));
}
private <t> collection<? extends t> getspringfactoriesinstances(class<t> type) {
return getspringfactoriesinstances(type, new class<?>[] {});
}
private <t> collection<? extends t> getspringfactoriesinstances(class<t> type,
class<?>[] parametertypes, object... args) {
classloader classloader = thread.currentthread().getcontextclassloader();
// 使用set確保的字符串的唯一性
set<string> names = new linkedhashset<string>(
springfactoriesloader.loadfactorynames(type, classloader));// 1.載入工廠名稱集合
list<t> instances = createspringfactoriesinstances(type, parametertypes,// 2.創建工廠實例
classloader, args, names);
annotationawareordercomparator.sort(instances);// 排序
return instances;
}

1.1 載入工廠名稱(loadfactorynames)

當前類的類加載器從 meta-inf/spring.factories 文件中獲取springapplicationrunlistener類的配置

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static list<string> loadfactorynames(class<?> factoryclass, classloader classloader) {
 string factoryclassname = factoryclass.getname();
 try {
 enumeration<url> urls = (classloader != null ? classloader.getresources(factories_resource_location) :
  classloader.getsystemresources(factories_resource_location));
 list<string> result = new arraylist<string>();
 while (urls.hasmoreelements()) {
  url url = urls.nextelement();
  properties properties = propertiesloaderutils.loadproperties(new urlresource(url));
  string factoryclassnames = properties.getproperty(factoryclassname);
  result.addall(arrays.aslist(stringutils.commadelimitedlisttostringarray(factoryclassnames)));
 }
 return result;
 }
 catch (ioexception ex) {
 throw new illegalargumentexception("unable to load [" + factoryclass.getname() +
  "] factories from location [" + factories_resource_location + "]", ex);
 }
 }

上圖,獲取到工廠類名后,下面來看看meta-inf/spring.factories中定義了啥:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# propertysource loaders
org.springframework.boot.env.propertysourceloader=\
org.springframework.boot.env.propertiespropertysourceloader,\
org.springframework.boot.env.yamlpropertysourceloader
# run listeners 這里呢,看這里!!!!
org.springframework.boot.springapplicationrunlistener=\
org.springframework.boot.context.event.eventpublishingrunlistener
# application context initializers
org.springframework.context.applicationcontextinitializer=\
org.springframework.boot.context.configurationwarningsapplicationcontextinitializer,\
org.springframework.boot.context.contextidapplicationcontextinitializer,\
org.springframework.boot.context.config.delegatingapplicationcontextinitializer,\
org.springframework.boot.context.embedded.serverportinfoapplicationcontextinitializer
# application listeners
org.springframework.context.applicationlistener=\
org.springframework.boot.clearcachesapplicationlistener,\
org.springframework.boot.builder.parentcontextcloserapplicationlistener,\
org.springframework.boot.context.fileencodingapplicationlistener,\
org.springframework.boot.context.config.ansioutputapplicationlistener,\
org.springframework.boot.context.config.configfileapplicationlistener,\
org.springframework.boot.context.config.delegatingapplicationlistener,\
org.springframework.boot.liquibase.liquibaseservicelocatorapplicationlistener,\
org.springframework.boot.logging.classpathloggingapplicationlistener,\
org.springframework.boot.logging.loggingapplicationlistener
# environment post processors
org.springframework.boot.env.environmentpostprocessor=\
org.springframework.boot.cloud.cloudfoundryvcapenvironmentpostprocessor,\
org.springframework.boot.env.springapplicationjsonenvironmentpostprocessor
# failure analyzers
org.springframework.boot.diagnostics.failureanalyzer=\
org.springframework.boot.diagnostics.analyzer.beancurrentlyincreationfailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.beannotofrequiredtypefailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.bindfailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.connectorstartfailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.nouniquebeandefinitionfailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.portinusefailureanalyzer,\
org.springframework.boot.diagnostics.analyzer.validationexceptionfailureanalyzer
# failureanalysisreporters
org.springframework.boot.diagnostics.failureanalysisreporter=\
org.springframework.boot.diagnostics.loggingfailureanalysisreporter

哇,都是些類全名稱,且key都是接口,value都是實現類。我們根據key=“ org.springframework.boot.springapplicationrunlistener ”查詢得到實現類value=" org.springframework.boot.context.event.eventpublishingrunlistener" 事件發布啟動監聽器 , 一猜也知道肯定要用” 反射 ”根據類名獲取類實例,下面很快得到驗證...

1.2 創建spring工廠實例(createspringfactoriesinstances)

根據第一步得到的set<string> names(springapplicationrunlistener的唯一實現類 eventpublishingrunlistener )生成" 事件發布啟動監聽器 " 工廠實例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@suppresswarnings("unchecked")
private <t> list<t> createspringfactoriesinstances(class<t> type,
class<?>[] parametertypes, classloader classloader, object[] args,
set<string> names) {
list<t> instances = new arraylist<t>(names.size());
for (string name : names) {
try {
 class<?> instanceclass = classutils.forname(name, classloader);// 利用反射獲取類
 assert.isassignable(type, instanceclass);
 constructor<?> constructor = instanceclass
 .getdeclaredconstructor(parametertypes);// 得到構造器
 t instance = (t) beanutils.instantiateclass(constructor, args);// 根據構造器和參數構造實例
 instances.add(instance);
}
catch (throwable ex) {
 throw new illegalargumentexception(
 "cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}

準備上下文

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private void preparecontext(configurableapplicationcontext context,
configurableenvironment environment, springapplicationrunlisteners listeners,
applicationarguments applicationarguments, banner printedbanner) {
context.setenvironment(environment);
postprocessapplicationcontext(context);//單例一個beannamegenerator,把resourceloader設置進應用上下文
applyinitializers(context);//執行初始化器
listeners.contextprepared(context);// 監聽器執行上下文"已準備好"方法
if (this.logstartupinfo) {
logstartupinfo(context.getparent() == null);
logstartupprofileinfo(context);
}
// 添加spring boot特殊單例bean
context.getbeanfactory().registersingleton("springapplicationarguments",
 applicationarguments);
if (printedbanner != null) {
context.getbeanfactory().registersingleton("springbootbanner", printedbanner);
}
// 載入資源
set<object> sources = getsources();
assert.notempty(sources, "sources must not be empty");
load(context, sources.toarray(new object[sources.size()]));
listeners.contextloaded(context);// 監聽器執行"上下文已加載"方法
}

刷新上下文

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void refreshcontext(configurableapplicationcontext context) {
refresh(context);//核心類
if (this.registershutdownhook) {
try {
context.registershutdownhook();//注冊關閉鉤子,容器關閉時執行
}
catch (accesscontrolexception ex) {
// not allowed in some environments.
}
}
}
protected void refresh(applicationcontext applicationcontext) {
assert.isinstanceof(abstractapplicationcontext.class, applicationcontext);
((abstractapplicationcontext) applicationcontext).refresh();
}

最終執行的是abstractapplicationcontext抽象類的 refresh 方法。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public void refresh() throws beansexception, illegalstateexception {
synchronized (this.startupshutdownmonitor) {
//準備刷新的上下文環境,例如對系統屬性或者環境變量進行準備及驗證。
preparerefresh();
//啟動子類的refreshbeanfactory方法.解析xml
configurablelistablebeanfactory beanfactory = obtainfreshbeanfactory();
//為beanfactory配置容器特性,例如類加載器、事件處理器等.
preparebeanfactory(beanfactory);
try {
 //設置beanfactory的后置處理. 空方法,留給子類拓展用。
 postprocessbeanfactory(beanfactory);
 //調用beanfactory的后處理器, 這些后處理器是在bean定義中向容器注冊的.
 invokebeanfactorypostprocessors(beanfactory);
 //注冊bean的后處理器, 在bean創建過程中調用.
 registerbeanpostprocessors(beanfactory);
 //初始化上下文中的消息源,即不同語言的消息體進行國際化處理
 initmessagesource();
 //初始化applicationeventmulticaster bean,應用事件廣播器
 initapplicationeventmulticaster();
 //初始化其它特殊的bean, 空方法,留給子類拓展用。
 onrefresh();
 //檢查并向容器注冊監聽器bean
 registerlisteners();
 //實例化所有剩余的(non-lazy-init) 單例bean.
 finishbeanfactoryinitialization(beanfactory);
 //發布容器事件, 結束refresh過程.
 finishrefresh();
}
catch (beansexception ex) {
 if (logger.iswarnenabled()) {
 logger.warn("exception encountered during context initialization - " +
 "cancelling refresh attempt: " + ex);
 }
 //銷毀已經創建的單例bean, 以避免資源占用.
 destroybeans();
 //取消refresh操作, 重置active標志.
 cancelrefresh(ex);
 // propagate exception to caller.
 throw ex;
}
finally {
 //重置spring的核心緩存
 resetcommoncaches();
}
}
}

刷新完上下文后

spring boot提供的2個供用戶自己拓展的接口: applicationrunner和 commandlinerunner。可以在容器啟動完畢后(上下文刷新后)執行,做一些類似數據初始化的操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void callrunners(applicationcontext context, applicationarguments args) {
list<object> runners = new arraylist<object>();
runners.addall(context.getbeansoftype(applicationrunner.class).values());//從上下文中獲取applicationrunner類型的bean
runners.addall(context.getbeansoftype(commandlinerunner.class).values());//從上下文中獲取commandlinerunner類型的bean
annotationawareordercomparator.sort(runners);//排序
for (object runner : new linkedhashset<object>(runners)) {
if (runner instanceof applicationrunner) {
 callrunner((applicationrunner) runner, args);//執行
}
if (runner instanceof commandlinerunner) {
 callrunner((commandlinerunner) runner, args);
}
}
}

兩個區別在于入參不同,根據實際情況自己選擇。

?
1
2
3
4
5
6
public interface commandlinerunner {
void run(string... args) throws exception;
}
public interface applicationrunner {
void run(applicationarguments args) throws exception;
}

commandlinerunner中執行參數是原始的 java啟動類main方法的string[] args字符串數組參數; applicationrunner中的參數經過處理提供一些方法例如:

?
1
list<string> getoptionvalues(string name);

根據名稱獲取值list,java 啟動命令中 --foo=bar --foo=baz,則根據foo參數名返回list ["bar", "baz"]

三、總結

spring boot容器啟動流程

按照前面的分析,spring-boot容器啟動流程總體可劃分為2部分:

1) 執行注解 :掃描指定范圍下的bean、載入自動配置類對應的bean加載到ioc容器。

2)man方法中具體springappliocation.run() ,全流程貫穿springapplicationevent,有6個子類:

?
1
2
3
4
5
6
applicationfailedevent.class
applicationpreparedevent.class
applicationreadyevent.class
applicationstartedevent.class
applicationstartingevent.class
springapplicationevent.class

這里用到了很經典的 spring事件驅動模型 ,飛機票: spring事件驅動模型和觀察者模式

類圖如下:

spring boot容器啟動流程

如上圖,就是一個經典spring 事件驅動模型,包含3種角色:事件發布者、事件、監聽者。對應到spring-boot中就是:

1 .eventpublishingrunlistener 這個類封裝了 事件發布 ,

2. springapplicationevent 是spring-boot中定義的事件(上面說的6種事件),繼承自 applicationevent (spring中定義的)

3. 監聽者 spring-boot并沒有實現針對上述6種事件的監聽者(我沒找到...), 這里用戶可以自己實現監聽者(上述6種事件)來注入spring boot容器啟動流程,觸發相應的事件。

例如:實現applicationlistener<applicationreadyevent>這個接口,在容器啟動完畢時最后一步listener.finished時,如果啟動沒有異常,就會執行!可以做一些數據初始化之類的操作。

總結

以上所述是小編給大家介紹的spring boot容器啟動的相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

原文鏈接:http://www.cnblogs.com/dennyzhangdd/p/8028950.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 成人免费视频视频 | 日本天天操 | 欧美大黄大色一级毛片 | 欧美成人精品欧美一级私黄 | 日日骚网| 色吧网站 | 国产精品视频导航 | 国内精品久久久久久 | 国产精品爱久久久久久久 | 久久国产亚洲 | 日韩中文字幕视频在线 | 91tv.com| 成人午夜精品久久久久久久3d | 欧美日韩一级视频 | 日韩电影免费在线观看 | 国产精品高清一区二区 | 国产高清一区 | 4虎tv| 亚洲免费观看 | 亚洲 欧美 日韩 丝袜 另类 | 欧美高潮 | 午夜视频免费在线观看 | 亚洲一区二区在线播放 | 久久久免费电影 | 欧美精品乱码久久久久久按摩 | 欧美视频免费 | 午夜国产在线 | 亚洲免费成人在线视频 | 成人免费视频 | 久久久高清| 高清国产一区二区三区 | 这里只有精品视频在线 | 日韩一区不卡 | 国产成人一区二区三区 | 国产欧美成人 | 蜜臀精品| 精品一区二区6 | 国内精品一区二区三区 | 免费看男女www网站入口在线 | 日韩精品免费一区二区三区 | 久久久久久99精品 |