스프링 클라우드가 인기가있는 순간, 기본 원칙을 이해하지 못하면 매우 혼란 스럽습니다 (구성보다 큰 계약이지만 원칙은 어떻습니까? 왜이를 수행해야합니까?). 스프링 클라우드는 스프링 부츠를 기반으로 빠르게 구축됩니다. 오늘 우리는 Spring Boot 컨테이너 시작 프로세스를 살펴볼 것입니다. (이 기사는 Spring Boot를 신속하게 시작하는 방법을 설명하지 않고 공식 웹 사이트, 공식 웹 사이트 문서 에어 티켓에서 직접 읽으십시오).
Spring Boot는 일반적으로 주 메소드를 시작한 다음 아래 그림과 같이 명령 줄에서 JAR 패키지를 시작하도록 컨테이너를 지정합니다.
@SpringBootApplicationPublic Class Application {public static void main (String [] args) {springApplication.run (application.class, args); }}다음은 다음과 같습니다.
1. @SpringBootApplication 주석
2. SpringApplication.run () 정적 메소드
이 두 내용을 아래에서 별도로 살펴 보겠습니다.
소스 코드는 다음과 같습니다.
@TARGET (ElementType.Type) @retention (rendentionPolicy.runtime) @documented @inherited @springbootconfiguration @enableautoconfiguration @componentscan (excludefilters = @filter (type = filtertype.custom, classes = elteexclfilter) FilterType.Custom, classes = AutoConFigurationExcludeFilter.class)}) public @Interface SpringBootApplication {핵심 노트 :
@SpringBootConfiguration (실제로 @Configuration) : JavaconFig 구성 클래스임을 의미합니다.이 클래스에서 Bean, 종속성 등을 사용자 정의 할 수 있습니다. -spring 스프링 부츠를위한 독특한 주석이며 일반적으로 사용됩니다.
@EnableAutoConfiguration : @Import의 도움으로 자동 구성 기준을 충족하는 모든 Bean 정의를 IOC 컨테이너에로드하십시오 (루트 패키지 경로 아래에 배치하는 것이 좋습니다. 하위 포장 및 클래스를 스캔 할 수 있습니다). -이것은 상세한 파기가 필요합니다!
@componentscan : 스캔 범위를 정의하고 IOC 컨테이너에로드 할 수있는 스프링의 자동 스캔 주석. -더 이상 이것을 말할 수 없습니다. 모두가 봄의 주석에 익숙해야합니다.
주석의 소스 코드 @enableautoconfiguration :
@SuppressWarnings ( "감가 상각") @Target (ElementType.Type) @retention (rendentionPolicy.Runtime) @documented @inherited @autoconfigurationpackage @import (enableAutoconFigurationImportSelector.class) public @interface enableautoconfiguration {핵심은 다음과 같이 enableautoconfigurationimportselector 클래스 다이어그램입니다.
핵심 메소드는 최상위 인터페이스 importselector에서 선택된 imports ()입니다. 소스 코드는 다음과 같습니다.
@override public String [] selectImports (AnnotationMetadata AnnotationMetadata) {if (! isenabled (anotationmetadata)) {return no_imports; } try {// 1. 로드 483 Meta-Inf/Spring-Autoconfigure-Metadata.properties 파일 (일부 기본값이 있음)의 구성 속성 (일부 기본값), AutoConfigurationMetadata AutoconFigurationMetadata = AutoConfigurationMetaloader .loadmetadata (this.BeanClassLoader); AnnotationAttributes 속성 = getAttributes (AnnotationMetadata); // 2. 주석 속성 목록 <string> configurations = getCandidAteConfigurations (AnnotationMetadata, // 3. GET 97 자동 구성 클래스 속성); 구성 = removeduplicates (구성); // 4. 중복 구성 = 정렬을 제거합니다 (구성, AutoConfigurationMetadata); // 5. 정렬 세트 <string> 제외 = getExclusions (AnnotationMetadata, Attributes); // 6. checkexcludedclasses (구성, 제외); // 7. 제외 된 클래스 구성을 확인하십시오 .removeall (제외); // 8. 제외 해야하는 모든 구성 삭제 = 필터 (구성, AutoConfigurationMetadata); // 9. OnclassCondition 필터 (주석에서 구성된 구성은 특정 클래스가 존재할 때만 적용됩니다) FireautoconfigurationImportevents (구성, Excclusions); // 10. 자동 구성 가져옵니다. 가져 오기 청취 이벤트 리턴 구성 .toArray (새 문자열 [configurations.size ()]); } catch (ioException ex) {Throw New ImperalStateException (EX); }}다음은 세 가지 핵심 방법입니다.
1) loadmetadata로드 구성
실제로, 클래스 로더를 사용하여 Meta-Inf/Spring-Autoconfigure-Metadata.properties (Spring-Boot-Autoconfigure-1.5.9. Release-Sources.jar) 파일에 정의 된 구성은 PropertieseAutoConfigurationMetadata (자산 회계 회계 및 Encapsetulates를 반환합니다.
2) getCandidAteConfigurations 기본 지원 자동 구성 클래스 이름 목록 가져 오기
소울 메소드, SpringFactoryLoader.loadFactoryNames 자동 구성 클래스 키 = ENABLEAUTOCONFIGURATION.CLASS의 구성을 가져옵니다.
보호 된 목록 <string> getCandidIteConfigurations (AnnotationMetAdata Metadata, AnnotationAttributes 속성) {// 맞습니다. 여기에 두 개의 매개 변수는 쓸모가 없습니다 ... 누가 나에게 설명 할 수 있습니다 ... List <stractoryNames (getSpringFactoryAldoryNames (getSpringFactoryClass), GetBeanClassClass (); Assert.notempty (구성, "meta-inf/spring.factories에서 찾은 자동 구성 클래스가 없습니다." + "가 사용자 정의 포장을 사용하는 경우 파일이 올바른지 확인하십시오."); 반환 구성; } // 리턴은 enableAutoConfiguration 클래스 보호 클래스 <?> getSpringFactoriorS.LoaderFactoryClass () {return enableAutoConfiguration.class입니다. }실제로 무엇을 얻었습니까? Spring.Factories 파일은 다음과 같습니다. 실제로 #auto 구성 자동 구성 모듈의 모든 클래스를 얻습니다.
# initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.autoconfigure.sharedMetAdatAreaderFactoryContexTinitializer,/org.springframework.autoconFigure.logurationReportLogingInitizer# Listenersorg.springframework.context.applicationListener =/org.springframework.boot.autoconfigure.backgroundpreinitializer# 자동 구성 가져 오기 Leargesorgorg.springframework.boot.autoconfigure.autoconfigurationimportlistener =/org.springframework.boot.autoconfigure.condition.conditionevaluationReporteAutoConfigurationImportLister# Auto Configuration 가져 오기 filtersorg.springframework.boot.autoconfigure.autoconfigurationimportfilter =/org.springframework.boot.autoconfigure.condition.onclassCondition# 여기에서 모든 자동 구성 클래스입니다. org.springframework.boot.autoconfigure.enableautoconfiguration =/org.springframework.boot.autoconfigure.admin.springApplicationAdminjmxAutoConfiguration,/org.springframework.boot.autoconfigure.aopeapaut ingframework.boot.autoconfigure.amqp.rabbitautoconfiguration,/org.springframework.boot.autoconfigure.batch.batchautoconfiguration,/org.springframework.boot.autoconfigure.cache.cacheautoconfiguration,/orgpring.spring.spring.spring .cassandra.cassandraeAutoconfiguration,/org.springframewort.boot.autoconfigure.cloud.cloudautoconfiguration,/org.springframework.boot.autoconfigure.context.conteptropertiesautoconfiguration,/org.springfringframwork. autoconconfure ontext.messagesOURCEAUTOCONFIGURATION,/org.springFramework.boot.autoconfigure.context.propertyPlaceHolderAutoConfiguration,/org.spramframewort.autoconfigure.couchbase.couchbaseeautoconfiguration,/orgpring.spring e.dao.persistenceExceptionTranslationAutoConfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandradataautoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandrorpositoriesateAutoconoconoconoconoconoconoconoconoconoconoconoconoconoconoconoconoconoconeconecontories rg.springframework.boot.autoconfigure.data.couchbase.couchbase.couchbaseataUatoconfiguration,/org.springframewort.autoconfigure.data.couchbase.couchbaseposerieseAutoconfiguration,/org.springframework.autoconfigure lasticsearchautoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchdataeAutoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchrepositorieseatoconfiguration,/org.spronff ramwork.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.mongo.mongorepositoriesaUtoconfiguration,/org.springfram.spram.spram.autoconfigure.data.neo4j.neo4j.nao4j.nao4j.nao4j.nao4j.neo4j.neo4j.neo4j.neo4j.neo4j.nao4j.neo4j.neo4j.neo4j.neo4j.neo4j.neo4j.neo4j.neo4j.neo4j.neo4j g.springframework.boot.autoconfigure.data.neo4j.neo4j.neo4jrepositoriesautoconfiguration,/org.springframework.autoconfig ure.data.solr.solrrepositoriesautoconfiguration,/org.springframework.autoconfigure.data.redis.redisautoconfigurati on,/org.springframework.boot.autoconfigure.data.redis.redisrepositoriesAutoconfiguration,/org.springframework.auto configure.data.rest.repositoryRestMVCautoConfiguration,/org.springframework.boot.autoconfigure.data.web.springdatawebau Toconfiguration,/org.springframework.boot.autoconfigure.elasticsearch.jest.jestautoconfiguration,/org.springframewort.autoconfigure.freemarker.freemarkerautoconfiguration,/org.springframewort.gsoneatoconfigure.gson.gson.gson.gson.gson.gsonfigure tion,/org.springframework.boot.autoconfigure.h2consoleautoconfiguration,/org.springframework.boot.autoconfigure.hateoas.hypermediaautoconfiguration,/org.sp ringframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,/org.springframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,/org.spring ngframework.boot.autoconfigure.hazelcast.hazelcastjpadependencyautoconfiguration,/org.springframework.boot.autoconfigure.info.projectinfoautoconfiguration,/org.springframework.autoconfigure.integration.integrationoconoconoconoconoconoconoconfigation.integration 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.xadatasourceauto 구성,/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.autoconfigur e.jms.ActiveMQ.ActiveMQUATOCONFIGURATION,/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.springframewort.autoconfigure.joo Q.jooqautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkaautoconfiguration,/org.springframework.autoconfigure.kafka.kafkaautoconfi gurate,/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.springfram.spramework.boot.autoconfigure.mobile.devicereresoleautoconefigereresoleautoconecon .springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,/org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,/org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAu Toconfiguration,/org.springframework.boot.autoconfigure.mongo.mongoautoconfiguration,/org.springframewort.boot.autoconfigure.mustache.mustacheautoconfiguration,/org.springframfram.autoconfigure.m.jpa.hiberatefa. /org.springframework.boot.autoconfigure.reactor.reactorautoconfiguration ,/org.springframework.boot.autoconfigure.security.security -autoconfiguration ,/org.spring Framework.boot.autoconfigure.security.securityfilterautoconfiguration,/org.springframework.boot.autoconfigure.security.securityfilterautoconfiguration,/org.spri ngframework.boot.autoconfigure.security.fallbackwebsecurityAutoconfiguration,/org.springframework.boot.autoconfigure.security.oauth2.outh2autoconfiguration ,/org.springframework.boot.autoconfigure.sendgrid.sendgridautoconfiguration,/org.springframework.boot.autoconfigure.sendgrid.sendgridautoconfiguration,/org. SpringFramework.boot.autoconfigure.session.sessionAutoconfiguration,/org.springframework.boot.autoconfigure.social.socialwebautoconfiguration,/org.springframework.boot.autoconfigure.social.faceoutoconfiguration,/orgpring.spring.spring OT.AutoConfigure.social.linkedinautoconfiguration,/org.springframework.boot.autoconfigure.social.twittereAutoconfigurati on,/org.springframework.boot.autoconfigure.solr.solrautoconfiguration,/org.springframework.boot.autoconfigure.thymelef .thymeleafautoconfiguration,/org.springframework.boot.autoconfigure.transaction.transactionAutoconfiguration,/org.springframewort.autoconfigure.transaction.jta.jta -autoconfiguration,/org.springframework.autoconfigure.validation.v AlidationAutoConfiguration,/org.springframework.boot.autoconfigure.web.dispatcherservletautoconfiguration,/org.springframewort.autoconfigure.web.embeddedServletcontainerautoconfiguration,/org.springframwork. autoconoconoconoconfuter errormvcautoconfiguration,/org.springframework.boot.autoconfigure.web.httpencodingautoconfiguration,/org.springframewor k.boot.autoconfigure.web.httpmessageconvertersatoconfiguration,/org.springframework.boot.autoconfigure.web.multipartaut Oconfiguration,/org.springframework.boot.autoconfigure.web.serverpropertiesautoconfiguration,/org.springframewort.autoconfigure.web.webclientAutoconfiguration,/org.s pringframework.boot.autoconfigure.websocket.websocketautoconfiguration,/org.springframework.boot.autoconfigure.websocket.websocketmessingagingAutoconfigipation,/org.sprameframework.autoconFigure.WebserVices.WebsErconOconOconFigation# 실패 Analyzersorg.springframework.boot.diagnostics.failureanalyzer =/org.springframework.boot.autoconfigure.diagnostics.analyzer.nosuchbeandefinitionfailureanalyzer,/org. 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.mustachetemplateavailabilityprovi der,/org.springframework.boot.autoconfigure.groovy.template.groovytemplateavailableprovider,/org.spramframework.autoconf igure.thymeleaf.thymeleaftemplateavailabilityprovider,/org.springframework.boot.autoconfigure.web.jsptemplateavailabilityprovider
3) 필터 필터는 OnclassCondition 주석을 충족하지 않는 조건을 필터링합니다.
개인 목록 <string> 필터 (List <string> 구성, AutoConfigurationMetadata AutoConfigurationMetadata) {long starttime = system.nanoTime (); 문자열 [] 후보자 = configurations.toArray (new String [configurations.size ()]); 부울 [] skip = new boolean [후보자 .length]; 부울 건너 뛰기 = 거짓; // 필터링 해야하는 자동 구성 가져 오기 요격기를 가져 오면 스프링에 하나만 있습니다. factories 구성 : org.springframework.boot.autoconfigure.condition.onclassCondition for (autoconfigurationImportFilter : getAutoConfigurationImportFilters ()) {reNCOCAWAROMED (FILOTOD); 부울 [] match = filter.match (후보자, AutoConfigurationMetadata); for (int i = 0; i <match.length; i ++) {if (! match [i]) {skip [i] = true; 건너 뛰기 = 참으로; }}} if (! smiphed) {// 하나의 불일치 -> 건너 뛰기 = true, 모든 일치 -》 건너 뛰기 = false-> 직접 반환 구성을 반환합니다. } list <string> result = new ArrayList <string> (후보자 .length); for (int i = 0; i <후보자.length; i ++) {if (! skip [i]) {// match-》 do n't skip- achat result.add에 추가하지 마십시오 (후보 [i]); }} if (logger.istraceEnabled ()) {int numberFiltered = configurations.size () - result.size (); logger.trace ( "필터링 된" + 숫자 필터링 + "자동 구성 클래스" + timeUnit.nanoseconds.tomillis (System.NanoTime () -StartTime) + "MS"); } return new arrayList <string> (결과); }SpringApplication.run
public configurableApplicationContext run (string ... args) {stopwatch stopwatch = new stopwatch (); stopwatch.start (); configurableApplicationContext context = null; FailureAnalyzers Analyzers = null; configureHeadsHeadsProperty (); SpringApplicationRunlisteners 리스너 = getRunListeners (Args); // 1. 청취자 리스너를 얻으십시오 .Starting ();-> 시작! {ApplicationArguments ApplicationArguments = new DefaultApplicationArguments (Args); 구성 가능한 환경 환경 = PreparenEnvironment (청취자, // 2. 환경을 준비하고 ApplicationEnvironmentpreparedEvent 이벤트 응용 프로그램을 트리거); 배너 printedbanner = printbanner (환경); // 시작 프롬프트 문자 인쇄, 기본 스프링 문자 다이어그램 컨텍스트 = CreateApplicationContext (); // 구성 가능한 응용 프로그램 컨텍스트 분석기를 인스턴스화합니다. prepareContext (컨텍스트, 환경, 청취자, 응용 프로그램, // 3. 컨텍스트 printedbanner 준비); refreshContext (컨텍스트); // 4. 컨텍스트를 새로 고침 (컨텍스트, 응용 프로그램); // 5. 컨텍스트 리스너를 새로 고침 한 후 피니쉬 (컨텍스트, null);-닫기! stopwatch.stop (); if (this.logstartupinfo) {new startUpInfologger (this.MainApplicationClass) .LogStarted (getApplicationLog (), stopWatch); } 반환 컨텍스트; } catch (Throwable ex) {handlerunfailure (컨텍스트, 청취자, 분석기, 예); 새로운 불법 상태를 던지십시오 (예); }}1. GetRunlisteners Get Listeners (SpringApplicationRunlisteners)
실제로 SpringApplicationRunlistener 클래스입니다
private springApplicationRunListeners getRunListeners (String [] args) {class <?> [] type = new Class <?> [] {springApplication.class, String []. class}; 새로운 SpringApplicationRunListeners를 반환합니다 (Logger, GetSpringFactorioryInstances (SpringApplicationRunlistener.Class, Type, This, Args)); } private <t> 수집 <? t> getSpringFactorioryInstances (class <t> type) {return getSpringFactorioryInstances (type, new class <?> [] {}); } private <t> 수집 <? t> getSpringfactorioryInstances (class <t> type, class <?> [] ParameterTypes, Object ... Args) {ClassLoader ClassLoader = Thread.CurrentThread (). getContextClassLoader (); // 문자열의 고유성을 보장하기 위해 세트를 사용하여 세트를 사용하십시오 <string> names = new LinkedHashset <string> (springfactoriordoLoader.loadFactoryNames (type, classloader)); // 1. 팩토리 이름 수집 목록 <T> Instances = CreateSpringFactorioryInstances (유형, ParameterTypes, // 2. Factory InstanceLoader, Args); AnnotationAwareOrderComparator.sort (인스턴스); // return 인스턴스를 정렬합니다. }1.1 공장 이름로드 (loadfactoryNames)
현재 클래스의 클래스 로더는 meta-inf/spring.cringories 파일에서 SpringApplicationRunlistener 클래스의 구성을 가져옵니다.
공개 정적 목록 <string> loadFactoryNames (class <?> factoryClass, ClassLoader ClassLoader) {String FactoryClassName = infactoryClass.getName (); {enumeration <URL> urls = (classLoader! = null? classload.getResources (actoriess_resource_location) : classLoader.GetSystemResources (actories_resource_location)를 시도합니다. List <string> result = new ArrayList <string> (); while (urls.hasmoreElements ()) {url url = urls.nextElement (); 속성 속성 = PropertiesLoaderUtils.loadProperties (new urlresource (url)); 문자열 factoryclassNames = properties.getProperty (incatoryClassName); result.addall (arrays.aslist (stringUtils.commadelimitedListToStringArray (FactoryClassNames))); } 반환 결과; } catch (ioException ex) {새로운 불법 행위 exception 던지기 ( "" + factoryClass.getName () + "] 공장 [" + 팩토리 _resource_location + "], ex); }}위의 그림에서 공장 클래스 이름을 얻은 후 Meta-Inf/spring.factories에서 정의 된 내용을 살펴 보겠습니다.
# PropertySource Loadersorg.springframework.boot.env.propertysourceloader =/org.springframework.env.env.propertiespropertysourceloader,/org.springframework.env.env.yamlpropertysourceler# 런리스리스# ! ! ! org.springframework.boot.springApplicationRunlistener =/org.springframework.boot.context.event.eventPublishingRunListener# 응용 프로그램 컨텍스트 Initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.context.configurationWarningsApplicationContextInitializer,/org.springframework.boot.context.contextid ApplicationContextInitializer,/org.springframework.boot.context.config.delegatingApplicationContextInitializer,/org.sprameframewort.context.embedded.serverportInfopplicationContextInitializer# Application Listenersorg.springframework.context.applicationListener =/org.springframework.boot.clearCachesApplicationListener,/org.springframework.builder.parentContextCloserap PlicationListener,/org.springframework.boot.context.fileencodingApplicationListener,/org.springframework.boot.context.config.ansioutputapplicationListener,/org.springfra mework.boot.context.config.configfileApplicationListener,/org.springframework.boot.context.config.delegateApplicationListener,/org.springframework.boot.liquibase.liqui BaseServicelocatorApplicationListener,/org.springframework.logging.classPathLoggingApplicationListener,/org.springframework.boot.logging.loggingApplicationListener# Environment Post Processorsorg.springframework.boot.env.environmentpostprocessor =/org.springframework.boot.cloud.cloudfoundfoundryvcapenvironmentpostprocessor,/org.sprameframework.env.springapplicationjsonenenvernmentprocessor# 실패 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.nouniquebeandefinitionfailureanalyzer, /org.springframework.boot.diagnostics.analyzer.portinusefailureanalyzer,/org.springframework.boot.diagnostics.analyzer.validationexceptionFailUreAnalyzer# FailUreAnalysisReportersorg.springframework.boot.diagnostics.failureanalysisreporter =/org.springframework.boot.diagnostics.loggingfailureanalysisreporter
와우,이 클래스에는 전체 이름이 있으며 키는 인터페이스이며 값은 구현 클래스입니다. key = "org.springframework.context.event.eventPublishingRunlistener"이벤트 릴리스를 기반으로 구현 클래스 value = "org.springframework.boot.springApplicationRunlistener"쿼리를 얻습니다. 일단 추측하면 클래스 이름에 따라 클래스 인스턴스를 얻으려면 "반사"를 사용해야합니다. 다음은 신속하게 확인되었습니다 ...
1.2 스프링 팩토리 인스턴스를 만듭니다
첫 번째 단계에서 얻은 세트 <string> 이름 (SpringApplicationRunlistener의 유일한 구현 클래스 EventPublishingRunlistener)을 기반으로 "EventPublishing Start Lispener"Factory 인스턴스 생성
@SuppressWarnings ( "Checked") Private <T> 목록 <T> 목록 <T> CreateSpringFactorioryInstances (Class <T> 유형, Class <?> [] ParameterTypes, ClassLoader ClassLoader, Object [] args, Set <string> 이름) {list <t> instances = new ArrayList <T> (Names.size ()); for (문자열 이름 : names) {try {class <?> instanceClass = classutils.forname (이름, classloader); // 반사를 사용하여 클래스 assert.isassignable (type, instanceclass)을 얻습니다. 생성자 <?> 생성자 = instanceClass .getDeclaredConstructor (ParameterTypes); // 생성자 t instance = (t) beanutils.instantiateClass (생성자, Args); // 생성자 및 파라미터 인스턴스를 기반으로 한 구성 인스턴스를 얻습니다. } catch (Throwable ex) {Throw New ImperalArgumentException ( "Instantiate" + type + ":" + name, ex); }} 반환 인스턴스; }컨텍스트를 준비하십시오
Private void prepareContext (configurableApplicationContext Context, ConfigurableEnvironment Environment, SpringApplicationRunListeners 리스너, 응용 프로그램 응용 프로그램, 배너 printedbanner) {context.setenvironment (환경); PostProcessApplicationContext (Context); // Singleton a BeanNameGenerator, ResourcelOader를 응용 프로그램 컨텍스트로 설정하는 컨텍스트 컨텍스트로 설정하십시오. null); logstartupprofileinfo (컨텍스트); } // 스프링 부팅 특수 Singleton Bean Context.getBeanFactory (). RegisterSingleton ( "SpringApplicationArguments", ApplicationArguments); if (printedbanner! = null) {context.getBeanFactory (). RegisterSingleton ( "SpringBootbanner", PrintedBanner); } // 리소스 세트를로드 <BORVERCESS = getSources (); assert.notempty (출처, "출처는 비어 있지 않아야한다"); 로드 (컨텍스트, 소스 .ToArray (새 개체 [sources.size ())); Learsers.contextloaded (컨텍스트); // 청취자는 "컨텍스트로드 된"메소드를 실행합니다}컨텍스트를 새로 고치십시오
private void refreshContext (configurableApplicationContext context) {새로 고침 (context); // core class if (this.registershutdownHook) {try {context.registershutdownHook (); 닫힌 후크 등록, 컨테이너가 닫힐 때 실행} {// 일부 환경에서는 허용되지 않습니다. }}} Protected void Refresh (ApplicationContext ApplicationContext) {assert.isinstanceof (AbstractApplicationContext.class, ApplicationContext); (((AbstractApplicationContext) ApplicationContext) .refresh (); }최종 실행은 AbstractApplicationContext Abstract 클래스의 새로 고침 메소드입니다.
public void refresh ()는 beansexception, 불법 스테이트 exception {synchronized (this.StartUpShutdownMonitor) {// 시스템 속성 또는 환경 변수 준비 및 확인과 같은 컨텍스트 환경을 새로 고치기 위해 준비합니다. repareerefresh (); // 서브 클래스의 RESHREATHBEANFACTORY 메소드를 시작합니다. 구문 분석 XML configurableDableBeanFactory beanfactory = acefreshBeanFactory (); // 클래스 로더, 이벤트 핸들러 등과 같은 BeanFactory의 컨테이너 기능 구성 (BeanFactory); {// 콩나무의 사후 처리를 설정하십시오. 빈 방법, 서브 클래스 확장을 위해 두십시오. 후 프로세스브 비앤비도 (beanfactory); // Bean 정의의 컨테이너에 등록 된 BeanFactory의 후 처리기를 호출합니다. InvokeBeanFactorypostprocessors (beanfactory); // Bean의 후 처리기를 등록하고 Bean Creation Process에서 호출하십시오. RegisterBeanPostProcessors (BeanFactory); // 컨텍스트에서 메시지 소스를 초기화합니다. // ApplicationEventMulticaster bean을 초기화하고 응용 프로그램 이벤트 방송사는 initApplicationEventMulticaster (); // 다른 특수 콩, 빈 방법을 초기화하고 서브 클래스 확장을 위해 남겨 두십시오. onrefresh (); // 리스너 Bean RegisterListeners ()를 확인하고 등록합니다. // 나머지 (비 게으른 이니트) 싱글 톤 빈 인스턴스. 마감 처리 (beanfactory); // 컨테이너 이벤트를 게시하고 새로 고침 프로세스를 종료합니다. FinishRefresh (); } catch (beansexception ex) {if (logger.iswarnenabled ()) {logger.warn ( "컨텍스트 초기화 중 예외 -" + "새로 고침 시도 :" + ex); } // 생성 된 싱글 톤 콩을 파괴하여 자원 소비를 피하십시오. Destroybeans (); // 새로 고침 작업을 취소하고 활성 플래그를 재설정합니다. CancelRefresh (예); // 발신자에게 예외를 전파합니다. ex 던지기; } 마침내 {// Spring의 핵심 캐시 재설정 ResetCommonCaches (); }}}컨텍스트를 새로 고침 한 후
Spring Boot는 사용자가 스스로 확장 할 수있는 두 개의 인터페이스를 제공합니다 : ApplicationRunner 및 CommandLinerUnner. 컨테이너가 시작된 후 (컨텍스트가 새로 고쳐진 후) 데이터 초기화와 유사한 일부 작업을 수행 할 수 있습니다.
개인 void CallRunners (ApplicationContext Context, ApplicationArguments Args) {list <botort> runners = new ArrayList <Object> (); Runners.addall (context.getBeansofType (ApplicationRunner.class) .values ()); // 컨텍스트 러너에서 ApplicationRunner의 getall (context.getBeansofType (commandlinerunner.class). AnnotationAwareOrderComparator.SORT (Runners); // 정렬 (개체 러너 : New LinkedHashset <bood> (Runners)) {if (runner instanceof ApplicationRunner) {CallRunner ((ApplicationRunner) Runner, Args); // execute} if (Callrunner) {(CommandLerunner); }}}두 가지 차이점은 매개 변수가 다르다는 것입니다. 실제 상황에 따라 직접 선택하십시오.
public Interface CommandLinerUnner {void run (String ... args)은 예외를 던집니다. } public Interface ApplicationRunner {void Run (ApplicationArguments Args)은 예외를 던집니다. }CommandLinerUnner의 실행 매개 변수는 원래 Java Startup Class 메인 메소드의 String [] args 문자열 배열 매개 변수입니다. ApplicationRunner의 매개 변수는 다음과 같은 일부 방법을 제공하도록 처리됩니다.
List <string> getOptionValues (문자열 이름);
Java startup 명령 --foo = bar --foo = baz, return list [ "bar", "baz"]에서 이름에 따라 값 목록을 가져옵니다. foo 매개 변수 이름에 따라
이전 분석에 따르면 스프링 부팅 컨테이너 시작 프로세스는 두 부분으로 나눌 수 있습니다.
1) 실행 주석 : 지정된 범위에서 Bean을 스캔하고 자동 구성 클래스에 해당하는 Bean을로드하여 IOC 컨테이너에로드하십시오.
2) MAN 메소드의 특정 springAppliocation.run ()은 SpringApplicationEvent를 통해 실행되며 6 개의 서브 클래스가 있습니다.
ApplicationFailedEvent.classApplicationPreparedEvent.classApplicationReadEvent.classApplicationStartEdevent.classApplicationStartIngevent.classSpringApplicationEvent.class
여기서 우리는 클래식 스프링 이벤트 중심 모델, 에어 티켓 : 스프링 이벤트 중심 모델 및 관찰자 모델을 사용합니다.
클래스 다이어그램은 다음과 같습니다.
위 그림에서 볼 수 있듯이 이벤트 게시자, 이벤트 및 리스너의 3 가지 역할을 포함하여 클래식 스프링 이벤트 중심 모델입니다. 스프링 부츠에 해당하는 것은 다음과 같습니다.
1. EventPublishingRunListener이 클래스는 이벤트 게시를 캡슐화하고,
2. SpringApplicationEvent는 Spring-Boot (위에서 언급 한 6 개의 이벤트)에 정의 된 이벤트입니다 (ApplicationEvent에서 상속) (스프링에 정의)
3. 监听者spring-boot并没有实现针对上述6种事件的监听者(我没找到...), 这里用户可以自己实现监听者(上述6种事件)来注入spring boot容器启动流程,触发相应的事件。
例如:实现ApplicationListener<ApplicationReadyEvent>这个接口,在容器启动完毕时最后一步listener.finished时,如果启动没有异常,就会执行!可以做一些数据初始化之类的操作。
요약
The above is the relevant knowledge about spring boot container startup introduced to you by the editor. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!