ในขณะที่สปริงคลาวด์เป็นที่นิยมมันสับสนมากถ้าคุณไม่เข้าใจหลักการพื้นฐาน (สิ่งที่คุณเห็นคือข้อตกลงที่ยิ่งใหญ่กว่าการกำหนดค่า แต่สิ่งที่เกี่ยวกับหลักการทำไมคุณต้องทำสิ่งนี้?) สปริงคลาวด์ถูกสร้างขึ้นอย่างรวดเร็วตามการบูตฤดูใบไม้ผลิ วันนี้เราจะดูกระบวนการเริ่มต้นของสปริงบูตคอนเทนเนอร์ (บทความนี้ไม่ได้อธิบายวิธีการเริ่มต้นฤดูใบไม้ผลิอย่างรวดเร็วเพียงแค่อ่านบทความโดยตรงบนเว็บไซต์อย่างเป็นทางการเอกสารทางอากาศของเว็บไซต์อย่างเป็นทางการ)
สปริงบูตโดยทั่วไประบุคอนเทนเนอร์เพื่อเริ่มวิธีการหลักแล้วเริ่มแพ็คเกจ JAR ในบรรทัดคำสั่งดังที่แสดงในรูปด้านล่าง:
@springbootapplicationpublic คลาสแอปพลิเคชัน {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {springapplication.run (application.class, args); -นี่คือสองสิ่ง:
1. @springbootapplication Annotation
2. Springapplication.run () วิธีการคงที่
มาสำรวจเนื้อหาทั้งสองนี้แยกกันด้านล่าง
ซอร์สโค้ดมีดังนี้:
@Target (ElementType.type) @retention (RetentionPolicy.runtime) @documented @inherited @springbootconfiguration @enableautoconfiguration @componentscan FilterType.custom, คลาส = AutoconFigurationExcludeFilter.class)}) สาธารณะ @interface Springbootapplication {หมายเหตุหลัก:
@SpringBootConfiguration (จริง @configuration): หมายความว่านี่คือคลาสการกำหนดค่า Javaconfig คุณสามารถปรับแต่งถั่วการพึ่งพา ฯลฯ ในชั้นเรียนนี้ -》 นี่คือคำอธิบายประกอบที่เป็นเอกลักษณ์สำหรับฤดูใบไม้ผลิและใช้กันทั่วไป
@EnableAutoconFiguration: ด้วยความช่วยเหลือของ @Import ให้โหลดคำจำกัดความถั่วทั้งหมดที่ตรงตามเกณฑ์การกำหนดค่าอัตโนมัติลงในคอนเทนเนอร์ IOC (ขอแนะนำให้วางไว้ใต้เส้นทางแพ็คเกจรูทเพื่อให้สามารถสแกนแพคเกจย่อยและคลาสได้) -》 สิ่งนี้ต้องใช้การขุดอย่างละเอียด!
@componentscan: คำอธิบายประกอบการสแกนอัตโนมัติของฤดูใบไม้ผลิซึ่งสามารถกำหนดช่วงการสแกนและโหลดลงในคอนเทนเนอร์ IOC -》 ไม่ต้องพูดแบบนี้อีกต่อไปทุกคนจะต้องคุ้นเคยกับคำอธิบายประกอบของฤดูใบไม้ผลิ
ซอร์สโค้ดของคำอธิบายประกอบ @enableautoconfiguration:
@suppresswarnings ("การเสียชีวิต") @target (ElementType.type) @retention (RetentionPolicy.runtime) @documented @inherited @autoconfigurationPackage @Importแกนกลางคือไดอะแกรมคลาส ENABLEAUTOCONFIGURATIONIMPORTSELECTER DIAGRAM ดังต่อไปนี้:
วิธีการหลักคือ SelectedImports () ในอินเตอร์เฟส importselector ระดับบนสุดซอร์สโค้ดมีดังนี้:
@Override สตริงสาธารณะ [] SelectImports (AnnotationMetadata AnnotationMetadata) {ถ้า (! isenabled (AnnotationMetadata)) {return no_imports; } ลอง {// 1 โหลดคุณสมบัติการกำหนดค่า 483 จากไฟล์ meta-inf/spring-autoconfigure-metadata.properties (บางส่วนมีค่าเริ่มต้น), autoconfigurationmetadata autoconfigurationMetadata = autoconfigurationMetAdataloader .loadmetadata AnnotationAttributes แอตทริบิวต์ = getAttributes (AnnotationMetadata); // 2 รับรายการแอตทริบิวต์คำอธิบายประกอบ <String> การกำหนดค่า = getCandidateConfigurations (AnnotationMetadata, // 3. รับ 97 แอตทริบิวต์คลาสการกำหนดค่าอัตโนมัติ); การกำหนดค่า = RemovedUplicates (การกำหนดค่า); // 4 ลบการกำหนดค่าที่ซ้ำกัน = sort (การกำหนดค่า, autoconfigurationmetadata); // 5 Sort Set <String> excludes = getExclusions (AnnotationMetadata, แอตทริบิวต์); // 6 รับ checkexcludedClasses (การกำหนดค่าไม่รวม); // 7 ตรวจสอบการกำหนดค่าคลาสที่แยกออกมา REMOVEALL (การยกเว้น); // 8 ลบการกำหนดค่าทั้งหมดที่จำเป็นต้องได้รับการยกเว้น = ตัวกรอง (การกำหนดค่า, autoconfigurationMetadata); // 9 ตัวกรอง onclassCondition (การกำหนดค่าในคำอธิบายประกอบจะมีผลเฉพาะเมื่อมีคลาสที่แน่นอน) fireautoconfigurationImportEvents (การกำหนดค่า, excclusions); // 10 ทริกเกอร์การกำหนดค่าการกำหนดค่าการกำหนดค่าอัตโนมัติการกำหนดค่าส่งคืนการกำหนดค่า toArray (สตริงใหม่ [configurations.size ()]); } catch (ioexception ex) {โยนใหม่ unlilmandalstateException (ex); -นี่คือ 3 วิธีหลัก:
1) การกำหนดค่าโหลด LoadMetadata
ในความเป็นจริงมันคือการใช้ตัวโหลดคลาสเพื่อโหลด: meta-inf/spring-autoconfigure-metadata.properties (Spring-boot-autoconfigure-1.5.9.2-sources.jar) การกำหนดค่าที่กำหนดไว้ในไฟล์ วิธี)
2) GetCandidAteconFigurations รับรายการชื่อคลาสการกำหนดค่าอัตโนมัติที่รองรับเริ่มต้น
กำหนดค่าเมธอดวิญญาณโดยอัตโนมัติ, SpringFactoriesLoader.loadFactoryNames ได้รับการกำหนดค่าของคีย์คลาสการกำหนดค่าอัตโนมัติ = enableAutoconFiguration.class จาก meta-inf/spring.factories (Spring-boot-autoconfigure-1.5.
รายการที่ได้รับการป้องกัน <string> getCandidateConfigurations (คำอธิบายประกอบข้อมูลเมตาดาต้าคำอธิบายประกอบ) คุณลักษณะ) {// ที่ถูกต้องพารามิเตอร์ทั้งสองที่นี่ไร้ประโยชน์ ... assert.notEmpty (การกำหนดค่า "ไม่พบคลาสการกำหนดค่าอัตโนมัติใน meta-inf/spring.factories ถ้าคุณ" + "ใช้บรรจุภัณฑ์ที่กำหนดเองตรวจสอบให้แน่ใจว่าไฟล์นั้นถูกต้อง"); ส่งคืนการกำหนดค่า; } // การส่งคืนคือคลาส enableAutoconFiguration คลาสที่ได้รับการป้องกันระดับ <?> getSpringFringFactoriesLoaderFactoryClass () {return enableAutoconFiguration.class; -คุณได้อะไรจริง? ไฟล์ Spring.Factories มีดังนี้ซึ่งจริง ๆ แล้วได้รับคลาสทั้งหมดของโมดูลการกำหนดค่าอัตโนมัติ #Auto
# initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.autoconfigure.sharedMetadatareaderFactoryContextinitializer listenersorg.springframework.context.applicationListener =/org.springframework.boot.autoconfigure.backgroundroundrearmentializer# นำเข้าการกำหนดค่าอัตโนมัติ listenersorg.springframework.boot.autoconfigure.autoconfigurationimportListener =/org.springframework.boot.autoconfigure.condition filtersorg.springframework.boot.autoconfigure.autoconfigurationImportFilter =/org.springframework.boot.autoconfigure.condition.onclassCondition# การกำหนดค่าอัตโนมัติที่นี่คือคลาสการกำหนดค่าอัตโนมัติทั้งหมด org.springframework.boot.autoconfigure.enableautoconfiguration =/org.springframework.boot.autoconfigure.admin.spr IngapplicationAdminjmxautoconfiguration,/org.springframework.boot.autoconfigure.aop.aopautoconfiguration,/org.spr ingframework.boot.autoconfigure.amqp.rabbitautoconfiguration,/org.springframework.boot.autoconfigure.batch.batchautocon รูปที่/org.springframework.boot.autoconfigure.cache.cacheautoconfiguration,/org.springframework.boot.autoconfigure .cassandra.cassandraautoconfiguration,/org.springframework.boot.autoconfigure.cloud.cloudautoconfiguration,/org.spring framework.boot.autoconfigure.context.configurationPropertiesautoconfiguration,/org.springframework.boot.autoconfigure.c ontext.messagesourceautoconfiguration,/org.springframework.boot.autoconfigure.context.propertyplaceholderautoconfiguration,/org.springframework.boot.autoconfigure.couchbase.couchbaseautoconfigion E.Dao.PersistenceExceptionTranslationAutoconFiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandr adataautoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandrarepositoriesautoconfiguration,/o rg.springframework.boot.autoconfigure.data.couchbase.couchbasedataautoconfiguration,/org.springframework.boot.autoconfi gure.data.couchbase.couchbaserepositoriesautoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.e Lasticsearchautoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchdataautoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.elastics ramework.boot.autoconfigure.data.jpa.jparepositoriesautoconfiguration,/org.springframework.boot.autoconfigure.data.ldap .ldapdataautoconfiguration,/org.springframework.boot.autoconfigure.data.ldap.ldaprepositoriesautoconfiguration,/org.spr ingframework.boot.autoconfigure.data.mongo.mongodataautoconfiguration,/org.springframework.boot.autoconfigure.data.mon. go.mongorepositoriesautoconfiguration,/org.springframework.boot.autoconfigure.data.neo4j.neo4jdataautoconfiguration/หรือหรือ g.springframework.boot.autoconfigure.data.neo4j.neo4jrepositoriesautoconfiguration,/org.springframework.boot.autoconfig ure.data.solr.solrrepositoriesautoconfiguration,/org.springframework.boot.autoconfigure.data.redis.redisautoconfigurati บน,/org.springframework.boot.autoconfigure.data.redis.redisrepositoriesautoconfiguration,/org.springframework.boot.auto configure.data.rest.repositoryrestmvcautoconfiguration,/org.springframework.boot.autoconfigure.data.web.springdatawebau toConfiguration,/org.springframework.boot.autoconfigure.elasticsearch.jest.jestautoconfiguration,/org.springframework.b oot.autoconfigure.freeMarker.freeMarkerautoconfiguration,/org.springframework.boot.autoconfigure.gson.gsonautoconfigura tion,/org.springframework.boot.autoconfigure.h2.h2consoleautoconfiguration,/org.springframework.boot.autoconfigure.hateoas.hypermediaautoconfiguration ringframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,/org.springframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,/org.spring ngframework.boot.autoconfigure.hazelcast.hazelcastjpadependencyautoconfiguration,/org.springframework.boot.autoconfigur e.info.projectinfoautoconfiguration,/org.springframework.boot.autoconfigure.integration.integrationautoconfiguration,/o rg.springframework.boot.autoconfigure.jackson.jacksonautoconfiguration,/org.springframework.boot.autoconfigure.jdbc.dat asourceautoconfiguration,/org.springframework.boot.autoconfigure.jdbc.jdbctemplateautoconfiguration,/org.springframewor K.BOOT.AUTOCONFIGURE.JDBC.JNDIDATASOURCEAUTOCONFIGURATION การกำหนดค่า,/org.springframework.boot.autoconfigure.jdbc.datasourcetransactionmanagerautoconfiguration,/org.springfra mework.boot.autoconfigure.jms.jmsautoconfiguration,/org.springframework.boot.autoconfigure.jmx.jmxautoconfiguration,/o rg.springframework.boot.autoconfigure.jms.jndiconnectionfactoryautoconfiguration,/org.springframework.boot.autoconfigurer e.jms.activemq.activemqautoconfiguration,/org.springframework.boot.autoconfigure.jms.aremis.artemisautoconfiguration,/ org.springframework.boot.autoconfigure.flyway.flywayautoconfiguration,/org.springframework.boot.autoconfigure.groovy.te mplate.groovytemplateautoconfiguration,/org.springframework.boot.autoconfigure.jersey.jerseyautoconfiguration,/org.spr ingframework.boot.autoconfigure.jooq.jooqautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkaautoconfi Guration,/org.springframework.boot.autoconfigure.ldap.embedded.embeddeddapautoconfiguration,/org.springframework.boot autoconfigure.ldap.ldapautoconfiguration,/org.springframework.boot.autoconfigure.liquibase.liquibaseautoconfiguration,/ org.springframework.boot.autoconfigure.mail.mailsenderautoconfiguration,/org.springframework.boot.autoconfigure.mail.m ailsendervalidatorautoconfiguration,/org.springframework.boot.autoconfigure.mobile.deviceresolverautoconfiguration,/org .springframework.boot.autoconfigure.mobile.devicedelegatingViewResolverautoconfiguration,/org.springframework.boot.auto configure.mobile.sitepreferenceautoconfiguration,/org.springframework.boot.autoconfigure.mongo.embedded.embeddedmongoau toConfiguration,/org.springframework.boot.autoconfigure.mongo.mongoautoconfiguration,/org.springframework.boot.autoconf Igure.mustache.mustacheautoconfiguration,/org.springframework.boot.autoconfigure.orm.jpa.hibernatejpaautoconfiguration /org.springframework.boot.autoconfigure.reactor.reactorautoconfiguration,/org.springframework.boot.autoconfigure.securityautoconfiguration framework.boot.autoconfigure.security.securityfilterautoconfiguration,/org.springframework.boot.autoconfigure.security.securityfilterautoconfiguration,/org.spri ngframework.boot.autoconfigure.security.fallbackwebsecurityautoconfiguration,/org.springframework.boot.autoconfigure.security.oauth2.oauth2autoconfiguration ,/org.springframework.boot.autoconfigure.sendgrid.sendgridautoconfiguration,/org.springframework.boot.autoconfigure.sendgrid.sendgridautoconfiguration/org springframework.boot.autoconfigure.session.sessionautoconfiguration,/org.springframework.boot.autoconfigure.social.soci alwebautoconfiguration,/org.springframework.boot.autoconfigure.social.facebookautoconfiguration,/org.springframework.bo ot.autoconfigure.social.linkedinautoconfiguration,/org.springframework.boot.autoconfigure.social.twitterautoconfigurati บน,/org.springframework.boot.autoconfigure.solr.solrautoconfiguration,/org.springframework.boot.autoconfigure.thymeleaf .THEMELEAFAUTOCONFIGURATION,/ORG.SPRINGFRAMEWORK.BOOT.AUTOCONFIGURE.Transaction.TransactionAutoconFiguration,/org.sprin gframework.boot.autoconfigure.transaction.jta.jtaautoconfiguration,/org.springframework.boot.autoconfigure.validation.v alidationautoconfiguration,/org.springframework.boot.autoconfigure.web.dispatcherservletautoconfiguration,/org.springf ramework.boot.autoconfigure.web.embeddedservletcontainerautoconfiguration,/org.springframework.boot.autoconfigure.web.e errormvcautoconfiguration,/org.springframework.boot.autoconfigure.web.httpencodingautoconfiguration,/org.springframewor k.boot.autoconfigure.web.httpmessageconvertersautoconfiguration,/org.springframework.boot.autoconfigure.web.multipartaut oconfiguration,/org.springframework.boot.autoconfigure.web.serverpropertiesautoconfiguration,/org.springframework.boot.autoconfigure.web.webclientautoconfiguration pringframework.boot.autoconfigure.websocket.websocketautoconfiguration,/org.springframework.boot.autoconfigure.websocket.websocketmessagingautoconfiguration ความล้มเหลว Analyzersorg.springframework.boot.diagnostics.failureanalyzer =/org.springframework.boot.autoconfigure.diagnostics.analyzer.nosuchebeandefinitionfailureanalyzer springframework.boot.autoconfigure.jdbc.datasourceBeancreationfailureanalyzer,/org.springframework.boot.autoconfigure.jdbc.hikaridriverconfigurationfailureanalyzer# ความพร้อมของแม่แบบ providersorg.springframework.boot.autoconfigure.template.templateavailabilityProvider =/org.springframework.boot.autoconfigure.fre Emarker.FreeMarkerTemplateavailabilityProvider,/org.springframework.boot.autoconfigure.mustache.mustachemplateavailabilityprovi der,/org.springframework.boot.autoconfigure.groovy.template.groovytemplateavailabilityprovider,/org.springframework.boot.autoconf igure.thymeleaf.thymeleaftemplateavailabilityprovider,/org.springframework.boot.autoconfigure.web.jsptemplateavailabilityprovider
3) ตัวกรองตัวกรองตัวกรองเงื่อนไขที่ไม่เป็นไปตามคำอธิบายประกอบการประชุม
รายการส่วนตัว <String> ตัวกรอง (รายการ <String> การกำหนดค่า, autoconfigurationMetadata autoconfigurationMetadata) {Long StartTime = System.Nanotime (); สตริง [] ผู้สมัคร = การกำหนดค่า toArray (สตริงใหม่ [configurations.size ()]); บูลีน [] skip = บูลีนใหม่ [ผู้สมัครความยาว]; บูลีนข้าม = false; // รับการสกัดกั้นการนำเข้าการกำหนดค่าอัตโนมัติที่ต้องกรองมีเพียงหนึ่งเดียวในฤดูใบไม้ผลิการกำหนดค่า: org.springframework.boot.autoconfigure.condition.onclassCondition บูลีน [] match = filter.match (ผู้สมัคร, autoconfigurationmetadata); สำหรับ (int i = 0; i <match.length; i ++) {if (! match [i]) {skip [i] = true; ข้าม = true; }}} if (! ข้าม) {// ตราบใดที่มีหนึ่งไม่ตรงกัน -> skipped = true, การจับคู่ทั้งหมด -》 ข้าม = false-> return โดยตรงเพื่อส่งคืนการกำหนดค่า; } รายการ <String> result = new ArrayList <String> (ผู้สมัครความยาว); สำหรับ (int i = 0; i <candidates.length; i ++) {ถ้า (! skip [i]) {// match-》 อย่าข้าม-》 เพิ่มลงในผลลัพธ์ results.add (ผู้สมัคร [i]); }} if (logger.istraceenabled ()) {int numberFiltered = configurations.size () - result.size (); logger.trace ("กรอง" + numberfiltered + "คลาสการกำหนดค่าอัตโนมัติใน" + timeunit.nanoseconds.tomillis (system.nanotime () - starttime) + "ms"); } ส่งคืน ArrayList ใหม่ <String> (ผลลัพธ์); -Springapplication.run
Public ConfigurableapplicationContext Run (String ... args) {StopWatch StopWatch = new StopWatch (); stopwatch.start (); ConfiguRableApplicationContext Context = NULL; เครื่องวิเคราะห์ Failureanalyzers = NULL; configureheadlessProperty (); SpringApplicationRunListeners Listeners = getRunListeners (args); // 1 รับฟังผู้ฟังเริ่มต้น ();-> เริ่ม! ลอง {ApplicationArguments ApplicationArguments = ใหม่ defaultApplicationArguments (ARGS); สภาพแวดล้อมที่กำหนดค่าได้ แบนเนอร์ printedbanner = printbanner (สภาพแวดล้อม); // พิมพ์อักขระพรอมต์เริ่มต้น, แผนผังอักขระสปริงเริ่มต้นบริบท = createApplicationContext (); // อินสแตนซ์แอปพลิเคชันบริบทแอปพลิเคชันที่กำหนดค่าได้ = ใหม่ failureanalyzers (บริบท); Preparecontext (บริบท, สภาพแวดล้อม, ผู้ฟัง, ApplicationArguments, // 3. เตรียมบริบท PrintedBanner); RefreshContext (บริบท); // 4 รีเฟรชบริบท AfterRefresh (บริบท, ApplicationArguments); // 5 หลังจากรีเฟรชผู้ฟังบริบทเสร็จแล้ว (บริบท, null); ปิด! stopwatch.stop (); if (this.logstartupInfo) {ใหม่ startupInfologger (this.mainapplicationClass) .logstarted (getApplicationLog (), stopwatch); } คืนบริบท; } catch (throwable ex) {handlerunfailure (บริบท, ผู้ฟัง, เครื่องวิเคราะห์, Ex); โยน unlueLstateException ใหม่ (EX); -1. getRunListeners รับผู้ฟัง (SpringApplicationRunListeners)
จริงๆแล้วมันเป็นคลาส SpringApplicationRunlistener
Private SpringApplicationRunListeners getRunListeners (String [] args) {คลาส <?> [] ประเภท = คลาสใหม่ <?> [] {SpringApplication.class, String []. class}; ส่งคืน SpringApplicationRunListeners ใหม่ (Logger, GetSpringFactoriesInstances (SpringApplicationRunListener.class, ประเภท, สิ่งนี้, args)); } collection ส่วนตัว <T> <? ขยาย t> getSpringFactoriesInstances (คลาส <t> ประเภท) {return getSpringFactoriesInstances (ประเภท, คลาสใหม่ <?> [] {}); } collection ส่วนตัว <T> <? ขยาย t> getSpringFactoriesInstances (คลาส <t> type, คลาส <?> [] พารามิเตอร์, วัตถุ ... args) {classloader classloader = tread.currentthread (). getContextClassLoader (); // ใช้ชุดเพื่อให้แน่ใจว่าเป็นเอกลักษณ์ของชุดสตริง <String> ชื่อ = ใหม่ LinkedHashSet <String> (SpringFactoriesLoader.loadFactoryNames (ประเภท, classloader)); // 1. โหลดรายการรวบรวมชื่อโรงงาน <t> อินสแตนซ์ = createspringFactories AnnotationAwareOrderComparator.sort (อินสแตนซ์); // เรียงลำดับอินสแตนซ์คืน; -1.1 การโหลดชื่อโรงงาน (LoadFactoryNames)
คลาสโหลดเดอร์ของคลาสปัจจุบันได้รับการกำหนดค่าของคลาส SpringApplicationRunListener จากไฟล์ META-INF/Spring.Factories
รายการคงที่สาธารณะ <String> loadFactoryNames (คลาส <?> FactoryClass, classloader classloader) {String FactoryClassName = FactoryClass.getName (); ลอง {enumeration <url> urls = (classloader! = null? classloader.getResources (factories_resource_location): classloader.getSystemResources (factories_resource_location)); รายการ <String> result = new ArrayList <String> (); ในขณะที่ (urls.hasmoreElements ()) {url url = urls.nextelement (); คุณสมบัติคุณสมบัติ = propertiesloaderutils.loadproperties (urlresource ใหม่ (URL)); String FactoryClassNames = properties.getProperty (FactoryClassName); result.addall (array.aslist (StringUtils.CommadeLimitedListToStringArray (FactoryClassNames))); } ผลตอบแทนผลลัพธ์; } catch (ioexception ex) {โยน unleglArgumentException ใหม่ ("ไม่สามารถโหลด [" + FactoryClass.getName () + "] โรงงานจากสถานที่ [" + factories_resource_location + "]", ex); -ในภาพด้านบนหลังจากได้รับชื่อคลาสโรงงานมาดูสิ่งที่กำหนดไว้ใน meta-inf/spring.factories:
# PropertySource Loadersorg.springFramework.boot.env.propertysourceloader =/org.springframework.boot.env.propertiespropertysourceloader,/org.springframework.boot.env.yamlproperty - - - org.springframework.boot.springapplicationrunlistener =/org.springframework.boot.contex initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.contex ApplicationContextInitializer,/org.springframework.boot.context.config.delegatingApplicationContextinitializer,/org.springframework.boot.context.embedded.serverportinfoaplication listenersorg.springframework.context.applicationListener =/org.springframework.boot.clearcachesapplicationListener,/org.springframework.boot.builder.parentcontextcloserap PlicationListener,/org.springframework.boot.contex mework.boot.context.config.configfileapplicationListener,/org.springframework.boot.contex baseservicelocatorapplicationListener,/org.springframework.boot.logging.classpathloggingapplicationListener,/org.springframework.boot.logging.loggingapplicationListener# สิ่งแวดล้อมโพสต์ pressorsorg.springframework.boot.env.environmentPostProcessor =/org.springframework.boot.cloud.cloud.cloudhoudryvcapenvironmentpostprocessor Analyzersorg.springframework.boot.diagnostics.failureanalyzer =/org.springframework.boot.diagnostics.analyzer.beancurrentyincreationfailureanalyzer,/org SpringFramework.boot.diagnostics.analyzer.beannotofrequiredtypefailureanalyzer,/org.springframework.boot.diagnostics.analyzer.bindfailureanalyzer,/org.spr ingframework.boot.diagnostics.analyzer.connectorstartfailureanalyzer,/org.springframework.boot.diagnostics.analyzer.nouniqueebeandefinitionfailureanalyzer /org.springframework.boot.diagnostics.analyzer.portinusefailureanalyzer,/org.springframework.boot.diagnostics.analyzer.validationexceptionfailureanalyzer# FailureanalysisReportersorg.springframework.boot.diagnostics.failureanalysisReporter =/org.springframework.boot.diagnostics.loggingfailureanalysis reporter
ว้าวคลาสเหล่านี้ทั้งหมดมีชื่อเต็มและคีย์เป็นอินเทอร์เฟซและค่าเป็นคลาสการใช้งาน เราได้รับค่าคลาสการใช้งาน = "org.springframework.boot.springapplicationrunlistener" ตามคีย์ = "org.springframework.boot.context.event.eventPublishingRunListener" เมื่อคุณเดาคุณต้องใช้ "การสะท้อนกลับ" เพื่อรับอินสแตนซ์คลาสตามชื่อคลาส ต่อไปนี้ได้รับการตรวจสอบอย่างรวดเร็ว ...
1.2 สร้างอินสแตนซ์ของโรงงานฤดูใบไม้ผลิ
สร้างอินสแตนซ์ของ "EventPublishing Start Listener" อินสแตนซ์จากชื่อ Set <string> (คลาสการใช้งานเพียงอย่างเดียว EventPublishRunlistener ของ SpringApplicationRunlistener) ที่ได้รับในขั้นตอนแรก
@suppresswarnings ("ไม่ได้ตรวจสอบ") ส่วนตัว <t> รายการ <t> createSpringFactoriesInstances (คลาส <t> ประเภท, คลาส <?> [] พารามิเตอร์ parameterTypes, classloader classloader, Object [] args, ตั้งค่า <string> ชื่อ) สำหรับ (ชื่อสตริง: ชื่อ) {ลอง {คลาส <?> instanceclass = classutils.forname (ชื่อ, classloader); // ใช้การสะท้อนเพื่อรับคลาส assert.isassignable (พิมพ์, instanceclass); ตัวสร้าง <?> constructor = instanceclass .getDeclaredConstructor (parameterTypes); // รับ instance t Instance = (t) beanutils.instantiateclass (constructor, args); // สร้างอินสแตนซ์ตามโครงสร้างและพารามิเตอร์ } catch (throwable ex) {โยน unlegalargumentException ใหม่ ("ไม่สามารถสร้างอินสแตนซ์" + type + ":" + name, ex); }} อินสแตนซ์ส่งคืน; -เตรียมบริบท
Private Void Preparecontext (ConfiguRableApplicationContext Context, สภาพแวดล้อมที่กำหนดค่าได้ของสภาพแวดล้อม, ผู้ฟัง SpringApplicationRunListeners, ApplicationArguments ApplicationArguments, Banner PrintedBanner) {context.setEnvironment (สภาพแวดล้อม); PostprocessApplicationContext (บริบท); // singleton a beannameGenerator ตั้งค่า ResourceLoader เป็นบริบทแอปพลิเคชัน appleInitializers (บริบท); // ดำเนินการเริ่มต้นฟังคำสั่งเริ่มต้น LogStartupprofileInfo (บริบท); } // เพิ่มสปริงบูตบริบทถั่วเดี่ยวพิเศษ getBeanFactory (). registersingleton ("SpringApplicationArguments", ApplicationArguments); if (printedbanner! = null) {context.getBeanFactory (). registersingleton ("Springbootbanner", PrintedBanner); } // โหลดชุดทรัพยากร <jobch> แหล่งที่มา = getSources (); assert.NotEmpty (แหล่งที่มา "แหล่งที่มาจะต้องไม่ว่าง"); โหลด (บริบท, แหล่งที่มา (วัตถุใหม่ [sources.size ()])); Listeners.ContextLoaded (บริบท); // ผู้ฟังดำเนินการวิธีการ "บริบทโหลด"}รีเฟรชบริบท
Private Void RefreshContext (ConfiguRableApplicationContext Context) {Refresh (บริบท); // core class ถ้า (this.registershutdownhook) {ลอง {context.registershutdownhook (); // ลงทะเบียนเบ็ดปิด, ดำเนินการเมื่อคอนเทนเนอร์ปิด} }}} การรีเฟรชเป็นโมฆะที่ได้รับการป้องกัน (ApplicationContext ApplicationContext) {assert.isinstanceOf (AbstractApplicationContext.class, ApplicationContext); ((AbstractApplicationContext) ApplicationContext) .REFRESH (); -การดำเนินการขั้นสุดท้ายคือวิธีการรีเฟรชของคลาสนามธรรม AbstractApplicationContext
Public Void Refresh () พ่น beansexception, ungelStateException {ซิงโครไนซ์ (this.startupshutdownmonitor) {// เตรียมที่จะรีเฟรชสภาพแวดล้อมบริบทเช่นการเตรียมและตรวจสอบคุณสมบัติของระบบหรือตัวแปรสภาพแวดล้อม Prepressfresh (); // เริ่มวิธีการรีเฟรชการผลิตของคลาสย่อย Parses XML configurableListableBeanFactory beanfactory = etaidfreshbeanfactory (); // กำหนดค่าคุณสมบัติคอนเทนเนอร์สำหรับ beanfactory เช่นตัวโหลดคลาสตัวจัดการเหตุการณ์ ฯลฯ prepareBeanFactory (beanfactory); ลอง {// ตั้งค่าโพสต์การประมวลผลของ beanfactory วิธีที่ว่างเปล่าทิ้งไว้สำหรับการขยายตัวย่อย postprocessbeanfactory (beanfactory); // โทรหา postprocessors ของ beanfactory ซึ่งลงทะเบียนกับคอนเทนเนอร์ในนิยามถั่ว InvokeBeanFactoryPostProcessors (BeanFactory); // ลงทะเบียน postprocessor ของถั่วและเรียกมันในระหว่างกระบวนการสร้างถั่ว RegisterBeanPostProcessors (BeanFactory); // เริ่มต้นแหล่งที่มาของข้อความในบริบทนั่นคือเนื้อหาข้อความในภาษาต่าง ๆ จะถูกประมวลผลในระดับสากล initMessagesource (); // เริ่มต้น ApplicationEventMulticaster Bean และผู้ประกาศข่าวแอปพลิเคชันคือ imitapplicationEventMulticaster (); // เริ่มต้นถั่วพิเศษอื่น ๆ วิธีการว่างเปล่าและปล่อยให้พวกเขาสำหรับการขยายตัวย่อย onrefresh (); // ตรวจสอบและลงทะเบียน Listener Bean RegisterListeners (); // อินสแตนซ์ทั้งหมดที่เหลืออยู่ FinishBeanFactoryInitialization (beanfactory); // เผยแพร่กิจกรรมคอนเทนเนอร์และสิ้นสุดกระบวนการรีเฟรช FinishRefresh (); } catch (beansexception ex) {ถ้า (logger.iswarnenabled ()) {logger.warn ("ข้อยกเว้นที่พบในระหว่างการเริ่มต้นบริบท -" + "การยกเลิกการรีเฟรชการรีเฟรช:" + ex); } // ทำลายถั่วซิงเกิลที่สร้างขึ้นเพื่อหลีกเลี่ยงการใช้ทรัพยากร Destroybeans (); // ยกเลิกการดำเนินการรีเฟรชและรีเซ็ตธงที่ใช้งานอยู่ Cancelrefresh (ex); // เผยแพร่ข้อยกเว้นให้กับผู้โทร โยนอดีต; } ในที่สุด {// รีเซ็ต Core Cache ResetCommonCaches (); -หลังจากรีเฟรชบริบท
Spring Boot ให้สองอินเทอร์เฟซสำหรับผู้ใช้เพื่อขยายตัวเอง: ApplicationRunner และ Commandlinerunner คุณสามารถดำเนินการบางอย่างที่คล้ายกับการเริ่มต้นข้อมูลหลังจากเริ่มต้นคอนเทนเนอร์ (หลังจากบริบทรีเฟรช)
Void Private CallRunners (บริบท ApplicationContext, ApplicationArguments args) {รายการ <jobch> runners = new ArrayList <Ojrop> (); runners.addall (บริบท. getBeansofType (ApplicationRunner.class) .values ()); // getall ของประเภทแอปพลิเคชันที่ใช้จากบริบท runners.addall (บริบท. getBeansoftype (commandlinerunner.class). (Object Runner: LinkedHashSet ใหม่ <Object> (Runners)) {ถ้า (Runner Instanceof ApplicationRunner) {CallRunner ((ApplicationRunner) Runner, args); // execute} ถ้า -ความแตกต่างสองประการคือพารามิเตอร์แตกต่างกันดังนั้นเลือกด้วยตัวเองตามสถานการณ์จริง
อินเตอร์เฟสสาธารณะ commandlinerunner {void run (string ... args) โยนข้อยกเว้น; } แอปพลิเคชันส่วนต่อประสานสาธารณะ {void run (applicationarguments args) โยนข้อยกเว้น; -พารามิเตอร์การดำเนินการใน CommandlinerUnner คือพารามิเตอร์สตริง [] args สตริงอาร์เรย์ของวิธีการหลักเริ่มต้น Java เริ่มต้น; พารามิเตอร์ใน ApplicationRunner ได้รับการประมวลผลเพื่อให้วิธีการบางอย่างเช่น:
รายการ <String> getOptionValues (ชื่อสตริง);
รับรายการค่าตามชื่อในคำสั่ง java startup -foo = bar -foo = baz จากนั้นส่งคืนรายการ ["bar", "baz"] ตามชื่อพารามิเตอร์ foo
จากการวิเคราะห์ก่อนหน้านี้กระบวนการเริ่มต้นของคอนเทนเนอร์สปริงบู๊ตสามารถแบ่งออกเป็น 2 ส่วน:
1) คำอธิบายประกอบการดำเนินการ: สแกนถั่วภายใต้ช่วงที่กำหนดโหลดถั่วที่สอดคล้องกับคลาสการกำหนดค่าอัตโนมัติและโหลดลงในคอนเทนเนอร์ IOC
2) Springappliocation.run () ในวิธีการของ MAN ทำงานผ่าน SpringApplicationEvent และมี 6 subclasses:
ApplicationFaileDevent.classapplicationPreparedEvent.ClassApplicationEvent.classapplicationStartedEvent.ClassApplicationStartingEvent.classspringapplicationEvent.class.classapplication
ที่นี่เราใช้โมเดลที่ขับเคลื่อนด้วยเหตุการณ์สปริงคลาสสิกตั๋วอากาศ: รุ่นที่ขับเคลื่อนด้วยเหตุการณ์ฤดูใบไม้ผลิและโมเดลผู้สังเกตการณ์
แผนภาพคลาสมีดังนี้:
ดังที่แสดงในภาพด้านบนมันเป็นโมเดลที่ขับเคลื่อนด้วยเหตุการณ์ฤดูใบไม้ผลิแบบคลาสสิกรวมถึง 3 บทบาท: Event Publisher, Event และ Listener สอดคล้องกับ Spring-Boot คือ:
1.VentPublishingRunListener คลาสนี้สรุปการเผยแพร่เหตุการณ์
2. SpringApplicationEvent เป็นเหตุการณ์ที่กำหนดไว้ใน Spring-Boot (6 เหตุการณ์ที่กล่าวถึงข้างต้น) ซึ่งสืบทอดมาจาก ApplicationEvent (กำหนดไว้ในฤดูใบไม้ผลิ)
3. ผู้ฟัง Spring-Boot ไม่ได้ใช้ผู้ฟังสำหรับเหตุการณ์ 6 ข้างต้น (ฉันไม่พบ ... ) Here users can implement the listener (the above 6 events) by themselves to inject the spring boot container startup process and trigger the corresponding event.
例如:实现ApplicationListener<ApplicationReadyEvent>这个接口,在容器启动完毕时最后一步listener.finished时,如果启动没有异常,就会执行!可以做一些数据初始化之类的操作。
สรุป
The above is the relevant knowledge about spring boot container startup introduced to you by the editor. I hope it will be helpful to you. หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!