Pada saat Spring Cloud populer, sangat membingungkan jika Anda tidak memahami prinsip -prinsip dasar (yang Anda lihat adalah perjanjian yang lebih besar dari konfigurasi, tetapi bagaimana dengan prinsipnya? Mengapa Anda perlu melakukan ini?). Spring Cloud dengan cepat dibangun berdasarkan boot musim semi. Hari ini kita akan melihat proses startup kontainer boot musim semi. (Artikel ini tidak menjelaskan cara memulai boot musim semi dengan cepat, cukup baca secara langsung di situs web resmi, tiket pesawat dokumen dokumen resmi)
Spring Boot umumnya menentukan wadah untuk memulai metode utama dan kemudian memulai paket JAR di baris perintah, seperti yang ditunjukkan pada gambar di bawah ini:
@SpringbootApplicationPublic Class Application {public static void main (string [] args) {springApplication.run (application.class, args); }}Berikut dua hal:
1. Anotasi @springbootApplication
2. Metode statis springapplication.run ()
Mari kita jelajahi dua konten ini secara terpisah di bawah ini.
Kode sumber adalah sebagai berikut:
@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 {Catatan Inti:
@Springbootconfiguration (sebenarnya @configuration): berarti bahwa ini adalah kelas konfigurasi JavaConfig, Anda dapat menyesuaikan kacang, dependensi, dll. Di kelas ini. -》 Ini adalah anotasi unik untuk boot musim semi dan umumnya digunakan.
@EnableAutoconfiguration: Dengan bantuan @Import, muat semua definisi kacang yang memenuhi kriteria konfigurasi otomatis ke dalam wadah IOC (disarankan untuk ditempatkan di bawah jalur paket root, sehingga subpupage dan kelas dapat dipindai). -》 Ini membutuhkan penggalian rinci!
@ComponentScan: Anotasi pemindaian otomatis pegas, yang dapat menentukan rentang pemindaian dan memuatnya ke dalam wadah IOC. -》 Tidak lagi mengatakan ini, semua orang harus terbiasa dengan anotasi musim semi.
Kode sumber anotasi @EnableAutoconfiguration:
@SuppressWarnings("deprecation") @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(EnableAutoConfigurationImportSelector.class) public @interface EnableAutoConfiguration {Inti adalah diagram kelas enableAutoconfigurationImportSelector sebagai berikut:
Metode inti adalah SelectectedImports () di ImportSelector antarmuka tingkat atas, kode sumber adalah sebagai berikut:
@Override public string [] selectImports (annotationmetadata annotationmetadata) {if (! IsEnabled (annotationmetadata)) {return no_imports; } coba {// 1. Muat 483 Properti Konfigurasi Dari File Meta-Inf/Spring-Autoconfigure-Metadata.Properties (beberapa memiliki nilai default), AutoConfigurationMetadata AutoConfigurationMetadata = AutoConfigurationMetAdataLoader. Muat METADATA (this.beanClassLoader); AnnotationAttributes Atribut = getAttributes (AnnotationMetadata); // 2. Dapatkan daftar atribut anotasi <string> configurations = getCandidateConfigurations (annotationmetadata, // 3. Dapatkan 97 atribut kelas konfigurasi otomatis); Configurations = Removeduplicates (Konfigurasi); // 4. Hapus konfigurasi duplikat = sortir (konfigurasi, autoconfigurationmetadata); // 5. Urutkan set <string> tidak termasuk = getExclusions (annotationmetadata, atribut); // 6. Dapatkan CHECKEXCLUDEDClasses (konfigurasi, tidak termasuk); // 7. Verifikasi konfigurasi kelas yang dikecualikan.removeall (pengecualian); // 8. Hapus semua konfigurasi yang perlu dikecualikan = filter (konfigurasi, autoconfigurationmetadata); // 9. Filter OnclassCondition (yang dikonfigurasi dalam anotasi hanya akan berlaku ketika kelas tertentu ada) fireautoconfigurationImportEventsEvents (konfigurasi, excclusions); // 10. Memicu konfigurasi automatik Impor Listening Event Return Configurations.toArray (string baru [configurations.size ()]); } catch (ioException ex) {lempar baru ilegalstateException (ex); }}Berikut 3 metode inti:
1) konfigurasi beban loadmetadata
Faktanya, ini adalah menggunakan class loader untuk memuat: meta-inf/spring-autoconfigure-metadata.properties (spring-boot-autoconfigure-1.5.9.release-source.jar) Konfigurasi yang ditentukan dalam file, mengembalikan propertiAutocOnfigurationMetAdata (menunjukkan autoconate (AutoCaPonate-Autoconate (AutoCaPonPIBATIONCATICATIONCATICEPOLATE (AutoCaPonPIRATIONSIPASI (AutoCaPonPIRATIONSICATICE (
2) GetCandateConfigurations Dapatkan Daftar Nama Kelas Konfigurasi Otomatis Didukung Default
Secara otomatis mengkonfigurasi metode soul, springFactoriesLoader.LoadFactoryNames Dapatkan konfigurasi kelas konfigurasi otomatis = enableAutoconfiguration.class dari file meta-inf/spring.
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {//That's right, the two parameters here are useless...Who can explain it to me... List<String> configurations = SpringFactoriesLoader.loadFactoryNames( getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notempty (konfigurasi, "tidak ada kelas konfigurasi otomatis yang ditemukan di meta-inf/spring.factories. Jika Anda" + "menggunakan kemasan khusus, pastikan file itu benar."); mengembalikan konfigurasi; } // Pengembalian adalah EnableAutOConfiguration Class Protected Class <?> GetSpringFactoriesLoquLoadFactoryClass () {return enableAutoconfiguration.class; }Apa yang sebenarnya Anda peroleh? File Spring.Factories adalah sebagai berikut, yang sebenarnya memperoleh semua kelas dari modul konfigurasi konfigurasi otomatis #Auto.
# Initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.autoconfigure.sharedMetadataReadererFactoryContextInalizer,/org.springframework.boot.autonfigure.loogging Listenersorg.springframework.context.applicationListener =/org.springframework.boot.autoconfigure.backgroundpreinitializer# Impor konfigurasi otomatis Auto Listenersorg.springframework.boot.autoconfigure.autoconfigurationImportListener =/org.springframework.boot.autoconfigure.condition.conditionevaluationreportAutoconfigurationImportListener# Konfigurasi Auto Konfigurasi Auto Konfigurasi Auto Auto Filtersorg.springframework.boot.autoconfigure.autoconfigurationImportFilter =/org.springframework.boot.autoconfigure.condition.oncondition# Auto Konfigurasi di sini adalah semua kelas konfigurasi otomatis. org.springframework ingframework.boot.autoconfigure.amqp.rabbitautoconfiguration,/org.springframework.boot.autoconfigure.batch.batchautocon Figuration,/org.springframework.boot.autoconfigure.cache.cacheautoconfiguration,/org.springframework.boot.autoconfigure .cassandra.cassandraautoconfiguration,/org.springframework.boot.autoconfigure.cloud.cloudautoconfiguration,/org.springframework.boOt.Autoconfigure.context.onfigurationpramertiesautonfiguration.Autoconfigure.context.configurationpriPertiesAtAutonfiguration.Outonfiguration, ORFACROP.ROPRAMING.ROPRAMING.ROPRAMRAMING.ORPORM.ROCRAMOR.ROUTROM.ROCRAMRIUP.CORFIG.ROCRAMURCURASE ontext.messageSourceAutoconfiguration,/org.springframework.boot.Autoconfigure.context.propertyplaceHolderAutoconfiguration,/org.springframework.boot.Autoconfigure.couchbase.couchbaseAteUutonfiguration e.dao.persistenceExceptionTranslationAutoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandr adataautoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandrarepositoryAutoconfiguration,/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.elasticsearchDataUutoconfiguration,/org.springframework.boot.Autoconfigure.data.elitticsearch.elasticsicreposticostions Ramework.boot.autoconfigure.data.jpa.jparepositoriesAutoconfiguration,/org.springframework.boot.autoconfigure.data.ldap .LdapDataAutoconfiguration,/org.springframework.boot.autoconfigure.data.ldap.ldaprepositoryAutoconfiguration,/org.spr ingframework.boot.autoconfigure.data.mongo.mongodatautoconfiguration,/org.springframework.boot.autoconfigure.data.mon go.mongorepositoriesAutoconfiguration,/org.springframework.boot.autoconfigure.data.neo4j.neo4jdatautoconfiguration,/atau g.springframework.boot ure.data.solr.solrrepositoryAutoconfiguration,/org.springframework.boot.autoconfigure.data.redis.redisautoconfigurati di,/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.hypermediautoconfiguration,/org.sp 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.xadataSourceauto Konfigurasi,/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.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.springframework.boot.autoconfigure.joo q.jooqautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkaautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkaautoconfi guration,/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.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.security.securityautoconfiguration ,/org.spring framework.boot.autoconfigure.security.securityfilterautoconfiguration,/org.springframework.boot.autoconfigure.security.securityfilterterautoconfiguration,/org.spri ngframework.boot.autoconfigure.security.fallbackWebSecurityAutoconfiguration,/org.springframework.boot.autoconfigure.security.oauth2uth2Autoconfiguration ,/org.springframework. springframework.boot.Autoconfigure.Session.SessionAutoconfiguration,/org.springframework.boot.Autoconfigure.social.socialwebAutoconfiguration,/org.spramework.boot.autoconfigure.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social.social ot.autoconfigure.social.linkedinautoconfiguration,/org.springframework.boot.autoconfigure.social.twitterautoconfigurati di,/org.springframework.boot.autoconfigure.solr.solrautoconfiguration,/org.springframework.boot.autoconfigure.thymeleaf .Tymeleafautoconfiguration,/org.springframework.boot.Autoconfigure.transaction.transactionautoconfiguration,/org.springframework.boot.Autoconfigure.transaction.jtautoconfonfiguration.boot.sring alidationautoconfiguration,/org.springframework.boot.Autoconfigure.web.dispatcherServletAutoconfiguration,/org.springframework.boot.Autoconfigure.web.we.pring -orgram.boUde.boUrponing.boUrfiG.WeB.ROWEURE.ROWEURE.ROWEURE.ROWEURE.ROWEURE.ROWEURE.ROWEURE.ROK.ROWEURE. 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,/org.s pringframework.boot.autoconfigure.websocket.websocketautoconfiguration,/org.springframework.boot.Autoconfigure.websocket.websocketmessagingAutoconfiguration,/org.springframework.toot.aot.aot analyzersorg.springframework.boot.diagnostics.failureAnalyzer =/org.springframework.boot.autoconfigure.diagnostics.analyzer.nosuchbeandefinitionfinureanalyzer,/org. springframework.boot.autoconfigure.jdbc.datasourceBeArcreationFailureAnalyzer,/org.springframework.boot.autoconfigure.jdbc.hikaridriverconfigurationfaileanalyzer# Ketersediaan template 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.groovytemplateAvailabilityProvider,/org.springframework.boot.autoconf igure.thymeleaf.thymeleaftemplateAvailabilityProvider,/org.springframework.boot.autoconfigure.web.jsptemplateavailabilityProvider
3) Filter Filter Filter Kondisi yang tidak memenuhi anotasi OnClassCondition
Daftar Pribadi <String> Filter (Daftar <String> Konfigurasi, AutoConfigurationMetAdata AutoConfigurationMetAdata) {Long StartTime = System.nanoTime (); String [] kandidat = configurations.toArray (string baru [configurations.size ()]); boolean [] skip = boolean baru [kandidat.length]; Boolean dilewati = false; // Dapatkan Konfigurasi Otomatis Impor Interceptor yang perlu difilter, hanya ada satu dalam konfigurasi Spring. boolean [] match = filter.match (kandidat, autoconfigurationmetadata); untuk (int i = 0; i <match.length; i ++) {if (! Match [i]) {lewati [i] = true; dilewati = true; }}} if (! dilewati) {// Selama ada satu ketidakcocokan -> dilewati = true, semua cocok -》 dilewati = false-> kembali langsung untuk mengembalikan konfigurasi; } Daftar <string> result = ArrayList baru <string> (kandidat.length); untuk (int i = 0; i <kandidat.length; i ++) {if (! lewati [i]) {// match-》 Jangan lewati-》 Tambahkan ke result hasil.add (kandidat [i]); }} if (logger.istraceEnabled ()) {int numberfiltered = configurations.size () - result.size (); Logger.trace ("Difiltered" + NumberFiltered + "Kelas Konfigurasi Otomatis di" + TimeUnit.nanoseconds.tomillis (System.nanoTime () - StartTime) + "MS"); } return new ArrayList <String> (hasil); }Springapplication.run
public configurableApplicationContext run (string ... args) {stopwatch stopwatch = stopwatch baru (); stopwatch.start (); ConfigurableApplicationContext Context = NULL; Analisis FailureAnalyzers = NULL; configureheadlessProperty (); SpringApplicationRunListeners listeners = getRunListeners (args); // 1. Dapatkan pendengar pendengar.Startting ();-> Mulai! coba {applicationArguments applicationArguments = new DefaultApplicationArguments (args); ConfigAbleNeNvironment Environment = PrepsionEnvironment (pendengar, // 2. Siapkan lingkungan dan memicu ApplicationEnvironmentPreparedEvent Acara ApplicationArguments); Banner PrintedBanner = Printbanner (Environment); // Cetak karakter prompt startup, diagram karakter pegas default konteks = createApplicationContext (); // instantiate analisis konteks aplikasi yang dapat dikonfigurasi = failureureanAnyzers baru (konteks); prepareContext (konteks, lingkungan, pendengar, applicationArguments, // 3. Siapkan konteks printedbanner); RefreshContext (konteks); // 4. Segarkan Konteks Afterrefresh (Konteks, ApplicationArguments); // 5. Setelah menyegarkan para pendengar konteks. Finished (konteks, null);-Tutup! stopwatch.stop (); if (this.logstartupInfo) {startupInfologger baru (this.mainApplicationClass) .logStarted (getApplicationLog (), stopwatch); } kembali konteks; } catch (Throwable ex) {handlerunfailure (konteks, pendengar, analisis, ex); Lempar IlegalStateException baru (EX); }}1. GetRunListeners mendapatkan pendengar (SpringApplicationRunListeners)
Itu sebenarnya adalah kelas springapplicationrunlistener
Private SpringApplicationRunListeners getRunListeners (string [] args) {class <?> [] type = class baru <?> [] {springapplication.class, string []. class}; Return New SpringApplicationRunListeners (Logger, GetSpringFactoriesInstances (SpringApplicationRunListener.class, tipe, ini, args)); } private <t> koleksi <? Extends t> getSpringFactoriesInstances (class <t> type) {return getSpringFactoriesInstances (type, class baru <?> [] {}); } private <t> koleksi <? memperluas t> getSpringFactoriesInstances (class <t> type, class <?> [] parameterTypes, objek ... args) {classloader classloader = thread.currentThread (). getContextClassLoader (); // Gunakan set untuk memastikan keunikan string set <string> names = new LinkedHashset <String> (springFactoriesLoader.LoadFactoryNames (Type, ClassLoader)); // 1. Muat daftar koleksi nama pabrik <t> instance = CreateSpringFactoriesInstances (type, parametertypes, // 2. AnnotationAwareOrdComparator.sort (instance); // urutkan pengembalian instance; }1.1 Memuat Nama Pabrik (LoadFactoryNames)
Kelas loader dari kelas saat ini mendapatkan konfigurasi kelas SpringApplicationRunListener dari file meta-inf/spring.factories
Daftar Statis Publik <String> LoadFactoryNames (Class <?> FactoryClass, ClassLoader ClassLoader) {String factoryClassName = factoryclass.getName (); Coba {enumeration <rerl> urls = (classloader! = null? classloader.getResources (factory_resource_location): classloader.getsystemResources (factory_resource_location)); Daftar <string> result = ArrayList baru <string> (); while (urls.hasmoreElements ()) {url url = urls.nextElement (); Properties Properties = PropertiesLoadUtils.LoadProperties (UrlResource baru (URL)); String factoryClasSnames = properties.getProperty (factoryclassname); result.addall (arrays.aslist (stringutils.CommadelimitedListToStringarray (factoryclassnames))); } hasil pengembalian; } catch (ioException ex) {lempar baru ilegalargumentException ("Tidak dapat memuat [" + factoryclass.getname () + "] pabrik dari lokasi [" + factory_resource_location + "]", ex); }}Dalam gambar di atas, setelah mendapatkan nama kelas pabrik, mari kita lihat apa yang didefinisikan dalam meta-inf/spring.
# PropertiesSource loaderSorg.springframework.boot.env.properysourceloader =/org.springframework.boot.env.propertiespropertysourceloader,/org.springframework.boot.env.yamLpropertySouroader# run linanis di sini, looking here, look.env.yamlpropertysourceloader# run here, hereal! Lai Lai Lai org.springframework.boot.springApplicationRunlistener =/org.springframework.boot.context.event.eventpublishingRunlistener# konteks aplikasi Initializersorg.springframework.context.applicationContextInitializer =/org.springframework.boot.context.configurationWarningsApplicationContextInitializer,/org.springframework.boot.context.contextId ApplicationContextInitializer,/org.springframework.boot.context.config.delegatingApplicationContextInitializer,/org.springframework.boot.context.embedded.serverportInfoApplicationContextInitializer Application# Listenersorg.springframework.context.applicationListener =/org.springframework.boot.clearcachesApplicationListener,/org.springframework.boot.builder.parentcontextCloserap PlicationListener,/org.springframework.boot.context.fileencodingApplicationListener,/org.springframework.boot.context.config.AnsioutputApplicationListener,/org.springfra mework.boot.context.config.configFileApplyCeristener,/org.springframework.boot.context.config.delegatingApplicationListener,/org.springframework.boot.liquibase.liqui BASESERVICELOCATATORAPLICEDICEDistener,/org.springframework.boot.logging.classpathloggingApplicationListener,/org.springframework.boot.logging.loggingApplicationListenerer# Lingkungan post processorg.springframework.boot.env.environmentpostprocessor =/org.springframework.boot.cloud.cloudfoundryvcapenvironmentpostprocessor,/org.springframework.boot.env.springApplicationJsonenenenventpostpostpostpost Analyzersorg.springframework.boot.diagnostics.failureAnalyzer =/org.springframework.boot.diagnostics.analyzer.beanCureChnya -contreationFailureAnalyzer,/org. springframework.boot.diagnostics.analyzer.beannotofrequiredtypeFailureAnyzer,/org.springframework.boot.diagnostics.analyzer.bindfailureanalyzer,/org.spr ingframework.boot.diagnostics.analyzer.connectorStartFailureAnalyzer,/org.springframework.boot.diagnostics.analyzer.nouniqueBeandefinitionFailureAnalyzer, /org.springframework.boot.diagnostics.analyzer.portinusefailureAnyzer ,/org.springframework.boot.diagnostics.analyzer.validationExceptionFailureanalyzer# Failurean analysisreportersorg.springframework.boot.diagnostics.failurean analysisreporter =/org.springframework.boot.diagnostics.loggingfailurean analysisReporter
Wow, semua kelas ini memiliki nama lengkap, dan kunci adalah antarmuka, dan nilai -nilai adalah kelas implementasi. Kami memperoleh nilai kelas implementasi = "org.springframework.boot.springapplicationrunlistener" kueri berdasarkan pada key = "org.springframework.boot.context.event.eventpublishingrunlistener" rilis acara dan memulai pendengar. Setelah Anda menebak, Anda harus menggunakan "refleksi" untuk mendapatkan instance kelas berdasarkan nama kelas. Berikut ini dengan cepat diverifikasi ...
1.2 Buat instance pabrik musim semi
Hasilkan Instance "EventPublishing Start Listener" berdasarkan nama set <string> (satu -satunya kelas implementasi EventPublishingRunListener dari SpringApplicationRunListener) yang diperoleh pada langkah pertama
@SuppressWarnings ("Uncecked") Private <T> Daftar <T> CreateSpringFactoriesInstances (type <T>, kelas <?> [] ParameterTypes, ClassLoader ClassLoader, Object [] args, atur <string> Nama) {list <t> instances = new arraylist <t> (names.size () {list <t> instances = ArrayList new ARRAYLIST <T> (names.size () untuk (nama string: nama) {coba {class <?> instanceClass = classutils.forname (nama, classloader); // gunakan refleksi untuk mendapatkan kelas assert.isassignable (type, instanceClass); Konstruktor <?> Konstruktor = InstanceClass .getDeclaredConstructor (ParameterTypes); // Dapatkan konstruktor t instance = (t) beanutils.instantiateclass (konstruktor, args); // konstruksi instance berdasarkan konstruktor dan parameter instances.add (contoh); } Catch (Throwable Ex) {Throw New IllegalArgumentException ("Can't Instantiate" + Type + ":" + Name, Ex); }} mengembalikan instance; }Persiapkan konteksnya
Private void prepareContext (ConfigurableApplicationContext Context, ConfigAbleNEnvironment Environment, SpringApplicationRunListeners Listeners, ApplicationArguments ApplicationArguments, Banner PrintedBanner) {Context.Setenvironment (Environment); postProcessApplicationContext(context);//Singleton a BeanNameGenerator, set the ResourceLoader into the application context applyInitializers(context);//Execute the initializer listeners.contextPrepared(context);//Listener execution context "Prepared" method if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logstartupprofileInfo (konteks); } // Tambahkan boot Spring Boot Khusus Singleton Bean Context.getBeanFactory (). Registersingleton ("SpringApplicationArguments", ApplicationArguments); if (printedBanner! = null) {context.getBeanFactory (). Registersingleton ("Springbootbanner", PrintedBanner); } // Muat Sumber Sumber Sumber <POBPENT> SUMBER = GetSources (); Assert.notempty (sumber, "sumber tidak boleh kosong"); muat (konteks, sumber.toArray (objek baru [sumber.size ()])); listeners.contextLoaded (konteks); // pendengar menjalankan metode "konteks dimuat"}Segarkan konteksnya
Private void RefreshContext (ConfigurableApplicationContext Context) {Refresh (Context); // Core Class if (this.registershutdownHook) {coba {context.registershutdownhook (); // daftarkan hook penutup, jalankan saat wadah ditutup} capscrey (accessControlexception ex) {excception {noing. }}} protected void refresh (ApplicationContext ApplicationContext) {assert.isInstanceOf (AbstractApplicationContext.class, ApplicationContext); ((AbstractApplicationContext) ApplicationContext) .refresh (); }Eksekusi akhir adalah metode refresh dari AbstractApplicationContext Abstract Class.
public void refresh () melempar BeansException, IllegalStateException {disinkronkan (this.startupshutDownMonitor) {// Bersiaplah untuk menyegarkan lingkungan konteks, seperti mempersiapkan dan memverifikasi properti sistem atau variabel lingkungan. preparerefresh (); // Mulai metode refreshbeanfactory dari subkelas. Parses XML ConfigurableListableBeanFactory beanFactory = ExtreFreshBeanFactory (); // Konfigurasikan fitur wadah untuk beanFactory, seperti class loader, event handler, dll. Persiapan Factory (beanFactory); Coba {// atur post-processing beanfactory. Metode kosong, biarkan untuk ekspansi subkelas. PostprocessBeanFactory (BeanFactory); // Hubungi postprosesor BeanFactory, yang terdaftar dengan wadah dalam definisi kacang. InvokeBeanFactoryPostProcessors (BeanFactory); // Daftarkan postprocessor kacang dan sebut saja selama proses penciptaan kacang. RegisterBeanPostProcessors (BeanFactory); // Inisialisasi sumber pesan dalam konteks, yaitu, badan pesan dalam berbagai bahasa diproses secara internasional initmessageSource (); // Inisialisasi ApplicationEventMulticaster Bean, dan penyiar acara aplikasi adalah InitApplicationEventMulticaster (); // Inisialisasi kacang khusus lainnya, metode kosong, dan tinggalkan untuk ekspansi subkelas. onrefresh (); // periksa dan daftarkan pendengar kacang registerlisteners (); // Contoh semua kacang singleton yang tersisa (non-lazy-init). finishbeanfactoryInitialisasi (beanfactory); // Publikasikan acara kontainer dan akhiri proses penyegaran. finishrefresh (); } catch (beansException ex) {if (logger.iswarnenabled ()) {logger.warn ("Pengecualian yang ditemui selama inisialisasi konteks -" + "Membatalkan upaya refresh:" + ex); } // Hancurkan kacang singleton yang dibuat untuk menghindari konsumsi sumber daya. DestroyBeans (); // Batalkan operasi penyegaran dan atur ulang bendera aktif. CancelRefresh (EX); // Perpanjakan pengecualian untuk penelepon. lempar ex; } akhirnya {// Reset Core Cache ResetCommonCaches (); }}}Setelah menyegarkan konteksnya
Spring Boot menyediakan dua antarmuka bagi pengguna untuk memperluas diri: ApplicationRunner dan CommandLinerner. Anda dapat melakukan beberapa operasi yang mirip dengan inisialisasi data setelah wadah dimulai (setelah konteksnya disegarkan).
Private Void CallRunners (ApplicationContext Context, ApplicationArguments args) {List <Papen> runners = ArrayList baru <Papen> (); runners.addall (context.getBeansOfType (applicationRunner.class) .values ()); // getall tipe applicationRunner dari runners context.addall (context.getBeansOfType (commandlinerner.class) .values ()); // getall commandlinerner dari commandlinerner. LinkedHashSet <BOMPERNT> (RUNNERS)) {if (runner instanceof applicationRunner) {callrunner ((applicationRunner) runner, args); // execute} if (runner instanceof commandlinerner) {callrunner ((commandlinerner) runner, args); }}}Kedua perbedaannya adalah bahwa parameternya berbeda, jadi pilihlah sendiri sesuai dengan situasi yang sebenarnya.
Public Interface CommandLinUnner {void run (String ... args) melempar pengecualian; } Public Interface ApplicationRunner {void run (ApplicationArguments args) melempar pengecualian; }Parameter eksekusi di CommandLinerner adalah string [] args string array parameter dari metode utama kelas startup java asli; Parameter dalam ApplicationRunner diproses untuk menyediakan beberapa metode seperti:
Daftar <String> getOptionValues (nama string);
Dapatkan Daftar Nilai sesuai dengan namanya, di perintah startup Java --foo = bar --foo = Baz, lalu daftar kembali ["bar", "Baz"] sesuai dengan nama parameter foo
Menurut analisis sebelumnya, proses startup kontainer pegas dapat dibagi menjadi 2 bagian:
1) Anotasi Eksekusi: Pindai biji di bawah rentang yang ditentukan, muat kacang yang sesuai dengan kelas konfigurasi otomatis dan memuatnya ke dalam wadah IOC.
2) SpringAppliocation.run () spesifik dalam metode pria berjalan melalui springapplicationEvent, dan ada 6 subclass:
ApplicationFailedEvent.ClassApplicationPreparedEvent.ClassApplicationReadEevent.ClassApplicationStartedEvent.ClassApplicationStartEvent.ClassSpringApplicationEvent.class
Di sini kami menggunakan model berbasis acara musim semi klasik, tiket pesawat: model musim semi dan model pengamat
Diagram kelas adalah sebagai berikut:
Seperti yang ditunjukkan pada gambar di atas, ini adalah model yang digerakkan oleh acara Spring Classic, termasuk 3 peran: penerbit acara, acara, dan pendengar. Sesuai dengan boot pegas adalah:
1.EventPublishingRunListenener kelas ini merangkum penerbitan acara,
2. SpringApplicationEvent adalah peristiwa yang didefinisikan dalam boot musim semi (6 peristiwa yang disebutkan di atas), diwarisi dari ApplicationEvent (didefinisikan dalam musim semi)
3. 监听者spring-boot并没有实现针对上述6种事件的监听者(我没找到...), 这里用户可以自己实现监听者(上述6种事件)来注入spring boot容器启动流程,触发相应的事件。
例如:实现ApplicationListener<ApplicationReadyEvent>这个接口,在容器启动完毕时最后一步listener.finished时,如果启动没有异常,就会执行!可以做一些数据初始化之类的操作。
Meringkaskan
The above is the relevant knowledge about spring boot container startup introduced to you by the editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!