En el momento en que Spring Cloud es popular, es muy confuso si no comprende los principios básicos (todo lo que ves son acuerdos que son mayores que la configuración, pero ¿qué pasa con el principio? ¿Por qué necesitas hacer esto?). Spring Cloud se construye rápidamente en función de Spring Boot. Hoy echaremos un vistazo al proceso de inicio del contenedor de arranque de primavera. (Este artículo no explica cómo comenzar rápidamente el arranque de primavera, solo lea los directamente en el sitio web oficial, el sitio web oficial documenta boletos aéreos)
Spring Boot generalmente especifica el contenedor para iniciar el método principal y luego iniciar el paquete JAR en la línea de comando, como se muestra en la figura a continuación:
@SpringBootApplicationPublic Aplolation {public static void main (string [] args) {springApplication.run (application.class, args); }}Aquí hay dos cosas:
1. @SpringBootApplication anotación
2. SpringApplication.run () Método estático
Exploremos estos dos contenidos por separado a continuación.
El código fuente es el siguiente:
@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 {Notas centrales:
@SpringBootConfiguration (en realidad @Configuration): significa que esta es una clase de configuración de Javaconfig, puede personalizar frijoles, dependencias, etc. en esta clase. -》 Esta es una anotación única para Boot Spring-Boot y se usa comúnmente.
@EnableAutoconfiguration: con la ayuda de @import, cargue todas las definiciones de frijoles que cumplan con los criterios de configuración automáticos en el contenedor del COI (se recomienda colocar debajo de la ruta del paquete raíz, de modo que los subpackages y clases se puedan escanear). -》 ¡Esto requiere una excavación detallada!
@ComponentsCan: Anotación de escaneo automático de Spring, que puede definir el rango de escaneo y cargarlo en el contenedor del COI. -》 No más para decir esto, todos deben estar familiarizados con las anotaciones de la primavera.
El código fuente de la anotación @enableAutoconfiguration:
@SupplesSwarnings ("Deprecation") @Target (elementType.type) @Retention (retentionPolicy.Runtime) @Documented @inherited @autoconfigurationPackage @Import (EnlleautoconfigurationImportSelector.classs) publicEl núcleo es un diagrama de clases de ImpanToconfigurationImportSelector de la siguiente manera:
El método central es selectedImports () En la interfaz de nivel superior ImportSelector, el código fuente es el siguiente:
@Override public String [] SelectImports (annotationMetadata AnnotationMetadata) {if (! IsEnabled (annotationMetadata)) {return no_imports; } try {// 1. Cargue 483 Propiedades de configuración del archivo Meta-INF/Spring-Autoconfigure-Metadata.Properties (algunos tienen valores predeterminados), autoconfigurationMetadata AutoconfigurationMetadata = AutoconfigurationMetAdataloader .LoadMetMetTata (this.BeanClassLoader); AnnotationAttributes atributos = getAttributes (anotationmetadata); // 2. Obtenga la lista de atributos de anotación <String> configuraciones = getCandidateConfigurations (AnnotationMetadata, // 3. Obtenga 97 atributos de clases de configuración automática); configuraciones = removedUpplicates (configuraciones); // 4. Eliminar configuraciones duplicadas = sort (configuraciones, autoconfigurationMetadata); // 5. Sort Set <String> Excludes = getExClusions (annotationMetadata, atributos); // 6. Obtener cheCkexCludedClasses (configuraciones, excluye); // 7. Verifique las configuraciones de clase excluidas.removeAll (exclusiones); // 8. Elimine todas las configuraciones que necesitan ser excluidas = Filtro (configuraciones, autoconfigurationMetadata); // 9. Filtro en ClassCondition (el configurado en la anotación solo entrará en vigencia cuando exista una determinada clase) FireUtoconfigurationImportEvents (configuraciones, exclusiones); // 10. Activar las configuraciones de devolución de evento de importación de la configuración automática. } Catch (ioException ex) {tirar nueva ilegalstateException (ex); }}Aquí hay 3 métodos centrales:
1) Configuración de carga de LoadMetadata
De hecho, es usar un cargador de clase para cargar: metainf/spring-autoconfigure-metadata.properties (spring-boot-autoconfigure-1.5.9.release-sources.jar) La configuración definida en el archivo, devuelve las propiedades de la propiedad de la propiedad de la propiedad (implementa la interfaz de metadata de autoconfiguración y las propiedades de la propiedad).
2) GetCandidateConfigurations Obtenga la lista de nombres de clase de configuración automática compatible predeterminada
Configurar automáticamente el método de soul, SpringFactoriesLoader.LoadFactoryNames Obtenga la configuración de la clase de configuración automática clave = EnableautOconfiguration.class desde el archivo metainf/spring.factories (spring-boot-eutoconfigure-1.5.9.release-sources.jars).
Lista protegida <String> getCandiDateConfigurations (metadatos annotationMetadata, annotationAttributes Attributes) {// Eso es correcto, los dos parámetros aquí son inútiles ... que pueden explicarlo a mí ... list <string> configuraciones = springfactoriesloader.loadFactoryNames (GetScringFactoriesgactorFactoryClasss (), getBeanClassLoadLoad ()););););););););););) Afirmar.notempty (configuraciones, "no hay clases de configuración automática que se encuentren en meta-inf/spring.factories. Si" + "está utilizando un empaque personalizado, asegúrese de que el archivo sea correcto"); configuraciones de devolución; } // El retorno es la clase de clase EnableAutOconfiguration de la clase protegida <?> }¿Qué has obtenido realmente? El archivo Spring.Factories es el siguiente, que en realidad obtiene todas las clases del módulo de configuración automática de configuración #AUTO.
# Initializersorg.springframework.context.ApplicationContextInitializer=/org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,/org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer# Application OyenteRorg.springframework.context.applicationListener =/org.springframework.boot.autoconfigure.backgroundpreinitializer# configuración automática importación OyenteSorg.springframework.boot.autoconfigure.autoconfigurationImportListener =/org.springframework.boot.autoconfigure.condition.conditionEvaluationReportAutoconfigurationImportListener# Auto Configuración import Filtersorg.springframework.boot.autoconfigure.autoconfigurationImportFilter =/org.springframework.boot.autoconfigure.condition.onclassCondition# configuración automática aquí son todas las clases de configuración automática org. 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.ConfigurationPropertiesAutoConfiguration,/org.springframework.boot.autoconfigure.c ontext.MessageSourCeautoconfiguration,/org.springframework.boot.autoconfigure.context.propertyplaceholderautoconfiguration,/org.springframework.boot.autoconfigure.couchbase.couchbaseutoconfiguration,/org.springframework.coutoconfonfurfonfigury e.dao.PersistenceExceptionTranslationAutoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandradataautoconfiguration,/org.springframework.boot.autoconfigure.data.cassandra.cassandraRepositoriesautiSautesautesautesautesautesautefiguration,/o ovalores. rg.springframework.boot.autoconfigure.data.couchbase.couchbasedataAutoconfiguration,/org.springframework.boot.autoconfi gure.data.couchbase.couchbasePositoriesAutoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.e LISTICSEARCHAUTOCONFIGURATION,/org.springframework.boot.autoconfigure.data.elasticsearch.elasticDataAutoconfiguration,/org.springframework.boot.autoconfigure.data.elasticsearch.elasticsearchRepositoriesautoconfiguration,/og.spreingfe ramework.boot.autoconfigure.data.jpa.jparepositoriesautoconfiguration,/org.springframework.boot.autoconfigure.data.ldap .DapDataAutoconfiguration,/org.springframework.boot.autoconfigure.data.ldap.DapRepositoriesAutoconfiguration,/org.spr ingframework.boot.autoconfigure.data.mongo.mongoDataAutoconfiguration,/org.springframework.boot.autoconfigure.data.mon GO.MongorepositoriesAutoconfiguration,/org.springframework.boot.autoconfigure.data.neo4j.neo4jdataautoconfiguration,/o g.springframework.boot.autoconfigure.data.neo4j.neo4jrepositoriesautoconfiguration,/org.springframework.boot.autoconfig ure.data.solr. On,/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.gsonautoconfiguura ción,/org.springframework.boot.autoconfigure.h2.h2consoleautoconfiguration,/org.springframework.boot.autoconfigure.hateoas.hypermediaautoconfiguration,/org.sp ringFramework.boot.autoconfigure.hazelcast.hazelcasautoconfiguration,/org.springframework.boot.autoconfigure.hazelcast.hazelcastautoconfiguration,/org.spring ngframework.boot.autoconfigure.hazelcast.hazelcastjpadependencyAutoconfiguration,/org.springframework.boot.autoconfigur E.Info.ProjectInfoautoconfiguration,/org.springframework.boot.autoconfigure.ingration.ingrationAutoconfiguration,/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.xadatasourceautouto Configuración,/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.autoconfurre.Joo q.Jooqautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkaautoconfiguration,/org.springframework.boot.autoconfigure.kafka.kafkautoconfi guration,/org.springframework.boot.autoconfigure.ldap.embedded.embeddeddldapautoconfiguration,/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.embeddedmongou 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.securityfilterautoconfiguration,/org.spri ngframework.boot.autoconfigure.security.fallbackwebsecurityautoconfiguration,/org.springframework.boot.autoconfigure.security.oaut.2.oauth2autoconfiguration ,/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.FacebookAutoConfiguration,/org.springframework.bo ot.autoconfigure.social.linkedinautoconfiguration,/org.springframework.boot.autoconfigure.social.twittaoconfigurati On,/org.springframework.boot.autoconfigure.solr. .ThyMeleafautoconfiguration,/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,/org.ss pringframework.boot.autoconfigure.websocket.webSocketAutoconfiguration,/org.springframework.boot.autoconfigure.websocket.webSocketMessessagingAutoconfiguration,/org.springframework.boot.autoconfigure.webservices.webservisesAutfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfonfiguration# AnalyzersOrg.springframework.boot.diagnostics.failureAnalyzer =/org.springframework.boot.autoconfigure.diagntics.analyzer.nosuchbeanDefinitionFailureAnalyzer,/org. springframework.boot.autoconfigure.jdbc.dataSourceBeAncreationFailureAnalyzer,/org.springframework.boot.autoconfigure.jdbc.hikaridriverConfigurationFailureAnyzer# Disponibilidad de plantilla Providersorg.springframework.boot.autoconfigure.template.templateAvailabilityProvider =/org.springframework.boot.autoconfigure.fre eMARKER.FREEMARKEMPLATEAVAILabilityProvider,/org.springframework.boot.autoconfigure.mustache.mustacheetemplateAvailabilityProvi der,/org.springframework.boot.autoconfigure.groovy.template.groovytemplataAvailabilityProvider,/org.springframework.boot.autoconf Igure.ThyMeleaf.ThyMelEftemplateAvailabilityProvider,/org.springframework.boot.autoconfigure.web.jsptemplataAvailabilityProvider
3) El filtro filtra filtra las condiciones que no cumplen con la anotación de OnClassCondition
Lista privada <String> Filter (List <String> Configuraciones, AutoconfigurationMetadata AutoconfigurationMetadata) {Long Starttime = System.Nanotime (); String [] candidates = configurations.toarray (new String [Configurations.Size ()]); booleano [] skip = nuevo booleano [candidates.length]; booleano omitido = falso; // Obtenga el Interceptor de importación automático de configuración que debe filtrarse, solo hay uno en la configuración de Spring.Factories: org.springframework.boot.autoconfigure.condition.onclassCondition para (autoconfigurationImportFilter Filter: getAutoconfigurationImportfilters ()) {Invokeawaremethods (filtro (filtro); boolean [] match = filtre.match (candidatos, autoconfigurationmetadata); for (int i = 0; i <match.length; i ++) {if (! Match [i]) {skip [i] = true; omitir = verdadero; }}} if (! Skipped) {// Mientras haya un desajuste -> Skipped = true, todas las coincidencias -》》》》》》》 false-> return directamente para devolver las configuraciones; } List <String> result = new ArrayList <String> (candidates.length); for (int i = 0; i <candidates.length; i ++) {if (! Skip [i]) {// Match-》 No saltee-》 Agregar al resultado resultado.Add (candidatos [i]); }} if (logger.istraceEnabled ()) {int numberFiltered = configurations.size () - resultado.size (); logger.trace ("filtrado" + numberFiltered + "clase de configuración automática en" + timeUnit.nanoseConds.tomillis (system.nanotime () - starttime) + "ms"); } return New ArrayList <String> (resultado); }Springapplication.run
Public ConfiguableApplicationContext run (String ... args) {stopwatch stopwatch = new StopWatch (); stopwatch.start (); ConfiguableApplicationContext context = null; Analizadores de fallurayalzers = nulo; configureheadlessproperty (); SpringApplicationRunListeners oyentes = GetRunListeners (args); // 1. Obtenga los oyentes oyentes.starting ();-> ¡Inicio! Pruebe {ApplicationArGuments ApplicationArGuments = new DefaultApplicationAarGuments (args); ConfigurableNenVironment Environment = PrepareEnvironment (oyentes, // 2. Prepare el entorno y active el evento AplicationEnmentPrepareVent Event AplicationAarGuments); Banner PrintedBanner = printBanner (entorno); // Imprima el carácter de inmediato de inicio, diagrama de caracteres de primavera predeterminado context = createApplicationContext (); // Instancia un análisis de contexto de aplicación configurable = new FauseAnalyzers (contexto); PrepareContext (contexto, entorno, oyentes, ApplicationArguments, // 3. Prepare el contexto impresoBanner); refreshContext (contexto); // 4. Actualice el contexto AfterRefresh (context, ApplicationArGuments); // 5. Después de actualizar los oyentes del contexto. Finished (contexto, nulo);-¡Cierre! stopwatch.stop (); if (this.logstartupinfo) {nuevo startupinfologger (this.mainapplicationClass) .logstarted (getApplicationLog (), stopwatch); } contexto de retorno; } catch (throwable ex) {handlerunfailure (contexto, oyentes, analizadores, ex); tirar nueva IllegalStateException (EX); }}1.
En realidad es la clase SpringApplicationRunlistener
SpringApplicationRunListeners privado GetRunListeners (String [] args) {class <?> [] tipos = new class <?> [] {springApplication.class, string []. class}; return New SpringApplicationRunListeners (Logger, GetSpringFactoriesInstances (SpringApplicationRunListener.class, tipos, este, args)); } colección privada <t> <? extiende t> getSpringFactoriesInstances (class <t> type) {return getSpringFactoriesInStances (type, nueva clase <?> [] {}); } colección privada <t> <? extiende t> getSpringFactoriesInStances (clase <t> type, class <?> [] ParametertyPes, Object ... args) {classloader classLoader = Thread.CurrentThread (). GetContextClassLoader (); // Use el conjunto para garantizar la singularidad de las cadenas Set <String> Names = new LinkedHashset <String> (SpringFactoriesLoader.LoadFactoryNames (type, classLoader)); // 1. Cargue la lista de colección de nombres de fábrica <T> Instancias = CreateSpringFactoriesInstances (type, ParametertyPes, // 2. Cree Factory Instance ClassLoader, Args, Names); nombres); AnnotationAwareRoRordComparator.sort (instancias); // clasificar instancias de retorno; }1.1 Nombre de fábrica de carga (LoadFactoryNames)
El cargador de clase de la clase actual obtiene la configuración de la clase SpringApplicationRunListener desde el archivo Meta-Inf/Spring.Factories
Public static List <String> LoadFactoryNames (class <?> FactoryClass, ClassLoader ClassLoader) {String factoryClassName = factoryClass.getName (); Pruebe {Enumeration <URL> urls = (classLoader! = NULL? ClassLoader.getResources (factories_resource_location): classloader.getSystemresources (fábrica_resource_location)); List <String> result = new ArrayList <String> (); while (urls.hasmoreelements ()) {url url = urls.nextelement (); Propiedades Propiedades = PropertiesLoaderUtilss.LoadProperties (new UrlResource (URL)); String FactoryClassNames = Properties.getProperty (factoryClassName); resultado.addall (arrays.aslist (stringUtils.commadelimitedListTtostringArray (FactoryClassNames))); } resultado de retorno; } Catch (ioException ex) {tirar nueva ilegalargumentException ("no se puede cargar [" + factoryClass.getName () + "] fábricas desde la ubicación [" + fábricas_resource_location + "]", ex); }}En la imagen de arriba, después de obtener el nombre de la clase de fábrica, echemos un vistazo a lo que se define en Meta-Inf/Spring.Factories:
# PropertySource LoaderSorg.springframework.boot.env.propertySourCelOaader =/org.springframework.boot.env.propertiespropertySourCeloader,/org.springframework.boot.env.yamlpropertysourceloader# dirige los oyentes aquí, ¡mira aquí, mira aquí! ! ! ! org.springframework.boot.springapplicationRunlistener =/org.springframework.boot.context.event.eventpublishingrunlistener# contexto de la aplicación InicialSersorg.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.serverportinfoapplationContextinitializer# aplicación OyenteSorg.springframework.context.applicationListener =/org.springframework.boot.cLearcachesApplicationListener,/org.springframework.boot.builder.parentContextCloserap plicationListener,/org.springframework.boot.context.fileCodingApplicationListener,/org.springframework.boot.context.config.anSioutputApplicationListener,/org.springfra mework.boot.context.config.configfileApplicationListener,/org.springframework.boot.context.config.delegatingAplicationListener,/org.springframework.boot.liquibase.liqui BaseServiceLocatorApplicationListener,/org.springframework.boot.logging.classpathloggingapplicationListener,/org.springframework.boot.logging.loggingapplicationListener# Entorno post procesadorsorg.springframework.boot.env.environmentPostprocessor =/org.springframework.boot.cloud.cloudfoundryvcapenvironmentPostPoscessor,/org.springframework.boot.env.spingaplicationJonVironmentPostPostPostPossprocessor# fallas AnalyzersOrg.springframework.boot.diagnostics.failureAnalyzer =/org.springframework.boot.diagnostics.analyzer.BeancurrentlyCreationFailureAlyzer,/org. SpringFramework.Boot.DiaGntics.analyzer.BeanNotOfRquiredTypeFailureAnyzer,/org.springframework.boot.diagnóstics.analyzer.bindfailureAnalyzer,/org.spr ingframework.boot.diagnostics.analyzer.connectorStartFailureAnalyzer,/org.springframework.boot.diagnostics.analyzer.nouniqueBeanDefinitionFailureAlyzer, /org.springframework.boot.diagnostics.analyzer.portinuseFailureAnalyzer./org.springframework.boot.diagnostics.analyzer.validationExceptionFailureAnyzer# FailureAnysiseReporterSorg.springframework.boot.diagnostics.failureAnysysisReporter =/org.springframework.boot.diagnostics.
Wow, todas estas clases tienen nombres completos, y las claves son interfaces, y los valores son clases de implementación. Obtenemos el valor de la clase de implementación = "org.springframework.boot.springapplicationRunListener" consulta basada en la clave = "org.springframework.boot.context.event.eventPublishingRunlistener" Liberación de eventos ". Una vez que adivine, debe usar "Reflexión" para obtener la instancia de clase basada en el nombre de la clase. Lo siguiente se verifica rápidamente ...
1.2 Crear instancias de fábrica de primavera
Genere una instancia de fábrica "EventPublishing Start Listener" basada en los nombres SET <String> (la única clase de implementación EventPublishingRunListener de SpringApplicationRunListener) obtenida en el primer paso
@SupplesSwarnings ("sin verificar") privado <t> list <t> CreateSpringFactoriesSinStances (class <t> type, clase <?> [] ParametertyPes, classloader classLoader, object [] args, establecer <string> nombres) {list <t> instancias = new ArrayList <T> (nombres.size ()); for (name de cadena: nombres) {try {class <?> Instanceclass = classUtils.forname (name, classLoader); // Use la reflexión para obtener la clase ASSERT.ISAsSignable (type, InstancECLass); Constructor <?> constructor = instancEclass .getDeClaredConstructor (ParametertyPes); // Obtener la instancia del constructor t = (t) beanutils.instantiateclass (constructor, args); // Instancias de construcción basadas en el constructor y parámetros instancias.add (instancia); } catch (throwable ex) {tire nueva ilegalargumentException ("no puede instanciar" + tipo + ":" + nombre, ex); }} Instancias de retorno; }Preparar el contexto
Private void PrepareContext (Contexto de configuración ConfigureApplicationContext, entorno ConfigurableNedment, SpringApplicationRunListeners oyentes, ApplicationArguments ApplicationArguments, Banner PrintedBanner) {context.setenVironment (entorno); PostProcessApplicationContext (context); // singleton a beanNameGenerator, establezca el resourceloader en el contexto de la aplicación AplicateInitializers (context); // Ejecutar inicializador de oyentes.contextprepared (context); // oyeker contexting "preparado" if (this.LogstarTupInfo) {logstarTupinfo (getArtArtArtement "(preparado" if (this (this.LogStarTupinfo) {logstarTupinfo (GetArtArtArtEntement "(preparado" si (this.LogStarTUnfo) {logstarTupinfo (getArtArtArtEctect "== /=); logstartUpprofileInfo (contexto); } // Agregar boot de primavera con contexto especial singleton bean.getBeanFactory (). RegisterSingLeton ("SpringApplicationArGuments", ApplicationArGuments); if (printedbanner! = null) {context.getBeanFactory (). RegisterSingLeton ("SpringBootBanner", PrintedBanner); } // Cargue el conjunto de recursos <ject> fuentes = getSources (); Afirmar.notempty (fuentes, "Las fuentes no deben estar vacías"); load (context, fuentes.toarray (nuevo objeto [fuentes.size ()])); oyentesActualizar el contexto
privado void refreshContext (configuración en contexto de ContextContext) {refresh (context); // Core class if (this.RegisterShutdownHook) {try {context.registerShutdownhook (); // Registre el anzuelo de cierre, ejecute cuando el contenedor está cerrado} Catch (AccessControleXception ex) {// no permitido en algunos entornos. }}} Protected void actual (ApplicationContext ApplicationContext) {ASSERT.ISINSTANTEOF (AbstractApplicationContext.Class, ApplicationContext); ((AbstractApplicationContext) ApplicationContext) .Refresh (); }La ejecución final es el método de actualización de la clase AbstractApplicationContext Abstract.
public void refresh () lanza BeanSexception, IllegalStateException {Synchronized (this.StartUpshutdownMonitor) {// Prepárese para actualizar el entorno de contexto, como preparar y verificar las propiedades del sistema o las variables de entorno. prepararerefresh (); // Inicie el método RefreshBeanFactory de la subclase. PARSES XML CONFIGURABLEISTABLEBENFACTORY BeanFactory = OBTRESHBEanFactory (); // Configure las características del contenedor para BeanFactory, como el cargador de clases, el controlador de eventos, etc. PrepareBeanFactory (BeanFactory); Pruebe {// Establezca el postprocesamiento de BeanFactory. Método vacío, déjelo para la expansión de la subclase. PostProcessBeanFactory (BeanFactory); // Llame a los postprocesadores de BeanFactory, que están registrados con el contenedor en la definición de frijoles. InvokeBeanFactoryPostProcessors (BeanFactory); // Registre el postprocesador de frijoles y llámalo durante el proceso de creación de frijoles. RegisterBeanPostProcessors (BeanFactory); // Inicializar la fuente de mensajes en el contexto, es decir, los cuerpos de mensajes en diferentes idiomas se procesan internacionalmente initMessageSource (); // Inicializar el bean AplicationEventMultCaster, y la emisora de eventos de aplicación es initApplicationEventMultCaster (); // Inicializa otros frijoles especiales, métodos vacíos y déjalos para la expansión de la subclase. onrefresh (); // Verifique y registra el Bean RegisterListeners (); // Instale todos los frijoles singleton restantes (inintería). finkbeanFactoryInitialization (beanFactory); // Publicar eventos de contenedores y finalizar el proceso de actualización. finkeRefresh (); } Catch (Beansexception ex) {if (logger.iswarnenable ()) {logger.warn ("excepción encontrada durante la inicialización del contexto -" + "cancelando el intento de actualización:" + ex); } // Destruir el frijol singleton creado para evitar el consumo de recursos. DestroyBeans (); // Cancelar la operación de actualización y restablecer el indicador activo. cancelRefresh (ex); // Propague la excepción a la persona que llama. tirar ex; } Finalmente {// RESTACIÓN CORACE CORE CORE SPRING RESETCOMMONCACHES (); }}}Después de refrescar el contexto
Spring Boot proporciona dos interfaces para que los usuarios se expandan: ApplicationRunner y CommandLinerunner. Puede realizar algunas operaciones similares a la inicialización de datos después de que se inicia el contenedor (después de que se actualice el contexto).
Private void callRunners (contexto de applicationContext, ApplicationArGuments Args) {List <S Object> Runners = New ArrayList <Sectus> (); runners.addall (context.getBeAnsofType (applicationRunner.class) .values ()); // getAll of type ApplicationRunner desde el context runners.addall (context.getBeanSoFType (commandlinerunner.class) .values ()); // get de type commandlinerner from the contextationAsarter.sort.sort (runers); (Object Runner: New LinkedHashset <SPET> (Runners)) {if (Runner instanceOf ApplicationRunner) {callRunner ((ApplicationRunner) Runner, Args); // ejecute} if (runner instanceOf commandlinerUnner) {callRunner ((CommandLinerUnner) Runner, Args); }}}Las dos diferencias son que los parámetros son diferentes, así que elija usted mismo de acuerdo con la situación real.
interfaz pública Commandlinerunner {void run (string ... args) lanza excepción; } Public Interface ApplicationRunner {Void Run (ApplicationArGuments Args) lanza una excepción; }Los parámetros de ejecución en CommandLinerUnner son los parámetros de matriz de cadena de cadena [] args del método principal de la clase de inicio Java original; Los parámetros en ApplicationRunner se procesan para proporcionar algunos métodos como:
List <String> getOptionValues (nombre de cadena);
Obtenga la lista de valores según el nombre, en el comando de inicio de Java --foo = bar --foo = baz, luego regrese la lista ["bar", "baz"] de acuerdo con el nombre del parámetro foo
Según el análisis anterior, el proceso de inicio del contenedor de bola de primavera se puede dividir en 2 partes:
1) Anotación de ejecución: escanee los frijoles en el rango especificado, cargue los frijoles correspondientes a la clase de configuración automática y los cargue en el contenedor del COI.
2) El SpringApplioCalation específico.
ApplicationFailEdevent.ClassApplicationPreparedEvent.ClassApplicationreadyEvent.ClassApplicationStartedevent.ClassApplicationStartingEvent.ClassSPringApplicationEvent.Class
Aquí utilizamos el modelo clásico de primavera, Ticket Air Ticket: Spring Event Drived Model y Observer Model
El diagrama de clases es el siguiente:
Como se muestra en la imagen de arriba, es un modelo clásico basado en eventos de primavera, que incluye 3 roles: editor de eventos, evento y oyente. Correspondiente al botín de primavera es:
1.EventPublishingRunListener Esta clase encapsula la publicación de eventos,
2. SpringApplicationEvent es un evento definido en Spring-Boot (los 6 eventos mencionados anteriormente), heredados de ApplicationEvent (definido en primavera)
3. 监听者spring-boot并没有实现针对上述6种事件的监听者(我没找到...), 这里用户可以自己实现监听者(上述6种事件)来注入spring boot容器启动流程,触发相应的事件。
例如:实现ApplicationListener<ApplicationReadyEvent>这个接口,在容器启动完毕时最后一步listener.finished时,如果启动没有异常,就会执行!可以做一些数据初始化之类的操作。
Resumir
The above is the relevant knowledge about spring boot container startup introduced to you by the editor. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!