Au moment où Spring Cloud est populaire, il est très déroutant si vous ne comprenez pas les principes de base (tout ce que vous voyez sont des accords supérieurs à la configuration, mais qu'en est-il du principe? Pourquoi avez-vous besoin de faire cela?). Spring Cloud est rapidement construit en fonction de Spring Boot. Aujourd'hui, nous allons jeter un œil au processus de démarrage du conteneur de démarrage de Spring. (Cet article n'explique pas comment démarrer rapidement Spring Boot, il suffit de lire ceux directement sur le site officiel, le site officiel Document Air Billets)
Spring Boot spécifie généralement le conteneur pour démarrer la méthode principale, puis démarrer le package JAR dans la ligne de commande, comme indiqué dans la figure ci-dessous:
@SpringBootApplicationPublic class Application {public static void main (String [] args) {springApplication.run (application.class, args); }}Voici deux choses:
1. @Springbootapplication annotation
2. SpringApplication.Run () Méthode statique
Explorons ces deux contenus séparément ci-dessous.
Le code source est le suivant:
@Target (elementType.Type) @retention (retenderPolicy.runtime) @Documented @Inherite FilterType.Custom, Classes = AutoConfigurationExCludFilter.class)}) public @Interface SpringbootApplication {Remarques de base:
@SpringBootConfiguration (en fait @configuration): signifie qu'il s'agit d'une classe de configuration Javaconfig, vous pouvez personnaliser les haricots, les dépendances, etc. dans cette classe. -》 Il s'agit d'une annotation unique pour le spring-boot et est couramment utilisée.
@EnableAutoConfiguration: avec l'aide de @Import, chargez toutes les définitions de bean qui répondent aux critères de configuration automatique dans le conteneur IOC (il est recommandé d'être placé sous le chemin du package racine, afin que les sous-packages et les classes puissent être analysés). -》 Cela nécessite une fouille détaillée!
@ComponentsCan: Annotation de balayage automatique du ressort, qui peut définir la plage de balayage et le charger dans le conteneur IOC. -》 Plus pour dire cela, tout le monde doit être familier avec les annotations du printemps.
Le code source de l'annotation @enableAutoConfiguration:
@SuppressWarnings ("Deprécation") @target (elementType.Type) @retention (retenderpolicy.runtime) @Documented @Inherited @autoConfigurationPackage @Import (enableAutoConfigurationImportSellectLe noyau est un diagramme de classe d'activation de la classe IMPortSelector comme suit:
La méthode principale est SelectedImporsts () Dans l'interface de niveau supérieur ImportSelector, le code source est le suivant:
@Override public String [] selectImports (annotationMetadata annotationMetAdata) {if (! IseNabled (annotationMetadata)) {return no_imports; } essayez {// 1. Chargez 483 Propriétés de configuration du fichier Meta-Inf / Spring-Autoconfigure-Metadata.Properties (certaines ont des valeurs par défaut), AutoConfigurationMetAdata AutoconfigurationMetAdata = AutoConfigurationMetAdataloder. ANNOTATATATTRIBUTES Attributs = GetAttributes (AnnotationMetadata); // 2. Obtenez la liste d'attribut d'annotation <string> configurations = getCanDateConfigurations (annotationMetadata, // 3. Obtenez 97 attributs de classes de configuration automatique); Configurations = supprimer les uplications (configurations); // 4. Supprimer des configurations en double = tri (configurations, autoconfigurationMetadata); // 5. Sort set <string> exclues = getExclusions (annotationMetadata, attributs); // 6. Obtenez CheckExCludClasses (configurations, exclues); // 7. Vérifiez les configurations de classe exclues.removeall (exclusions); // 8. Supprimez toutes les configurations qui doivent être exclues = filtre (configurations, autoconfigurationMetadata); // 9. Filtre OnClassCondition (le configuré dans l'annotation ne prendra effet que lorsqu'une certaine classe existe) FIREAUTOCONFIGIGURATIONIMPORTEVENTS (configurations, excclusions); // 10. Déclenchez la configuration automatique d'importation d'événement d'écoute de return configurations.toArray (new String [configurations.size ()]); } catch (ioException ex) {lancer un nouveau illégalStateException (ex); }}Voici 3 méthodes de base:
1) Configuration de charge de chargement de chargement
En fait, il s'agit d'utiliser un chargeur de classe pour charger: Meta-Inf / Spring-Autoconfigure-Metadata.Properties (Spring-Boot-AutoConfigure-1.5.9.Release-Sources.jar) La configuration définie dans le fichier, Returns PropertiesAutoConfigurationMetadata (implémente l'interface AutoConfigurationMetadata et encapte l'interface de l'autoconfigalisation méthode)
2) GetcandidateConfigurations Obtenez la liste de noms de classe de configuration automatique pris en charge par défaut
Configurez automatiquement la méthode de l'âme, SpringFactoriesLoader.LoadFactoryNames obtient la configuration de la classe de configuration automatique Key = ENABLAUTOCONFIGURATION.CLASSE du fichier meta-inf / printemps.factories (printemps-boot-autoconfigure-1.5.9.9release-Sources.jar).
Liste protégée <string> getcandidateconfigurations (annotationMetadata Metadata, annotationAtButes Attributs) {// c'est vrai, les deux paramètres ici sont inutiles ... qui peuvent expliquer à moi ... la liste <string> Configurations = SpringFactoriesLoader.LoadFactoryNames (getPringFactoriesLoDerFactoryClass (), getBames ()); Assert.notempty (Configurations, "Aucune classe de configuration automatique trouvée dans Meta-inf / Spring.factories. Si vous" + "utilisez un emballage personnalisé, assurez-vous que le fichier est correct."); configurations de retour; } // Le retour est la classe Protected Class Protected Class Protected <?> GetSpringFactoriesFactoryClass () {return perteAutoConfiguration.class; }Qu'avez-vous réellement obtenu? Le fichier Spring.factories est le suivant, qui obtient en fait toutes les classes du module de configuration automatique de configuration #Auto.
# Initialisersorg.springframework.context.applicationContextInitializer = / org.springframework.boot.autoconfigure.sharedmetaDataReaderFactoryContextinitializer, / org.springframework.boot.autoconfigure.Logging.AutoconfigurationRe Auditersorg.springframework.context.applicationListener = / org.springframework.boot.autoconfigure.backgroundpreinitializer # Importation de configuration automatique Listenersorg.springframework.boot.autoconfigure.AutoConfigurationImportListener=/org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener# Auto Configuration Import Filtersorg.springframework.boot.autoconfigure.autoconfigurationImportFilter = / org.springframework.boot.autoconfigure.condition.onclasscondition # Auto Configure ici sont toutes les classes de configuration automatique org.springframework.boot.autoconfigure.enableAutoConfiguration = / org.springframework.boot.autoconfigure.admin.springApplicationAdminjmxAutoConfiguration, / org.springframework.boot.autoconfigure.aop.Aopautoconfiguration, / org.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr.spr. ingframework.boot.autoconfigure.amqp.rabbitautoconfiguration, / org.springframework.boot.autoconfigure.batch.batchautocon Figation, / org.springframework.boot.autoconfigure.cache.cacheautoconfiguration, / org.springframework.boot.autoconfigure .cassandra.cassandraautoconfiguration, / org.springframework.boot.autoconfigure.cloud.cloudautoconfiguration, / org.springframework.boot.autoconfigure.context.configurationpropertiesAutoCure.Conde ontext.MessageSourceAutoConfiguration,/org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,/org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,/org.springframework.boot.autoconfigur e.dao.PersistenceExceptionStRanSlationAutoConfiguration, / org.springframework.boot.autoconfigure.data.cassandra.cassandrr adataautoconfiguration, / org.springframework.boot.autoconfigure.data.cassandra.cassandrarepositiensautoconfiguration, / 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.ElasticsearchRepositoriesAutoConfiguration,/org.springf ramework.boot.autoconfigure.data.jpa.jparepositiensautoconfiguration, / org.springframework.boot.autoconfigure.data.ldap .Ldapdataautoconfiguration, / org.springframework.boot.autoconfigure.data.ldap.ldaprepositiensautoconfiguration, / org.spr ingframework.boot.autoconfigure.data.mongo.mongodataautoconfiguration, / org.springframework.boot.autoconfigure.data.mon go.mongorepositienesautoconfiguration, / org.springframework.boot.autoconfigure.data.neo4j.neo4jdataautoconfiguration, / ou g.springframework.boot.autoconfigure.data.neo4j.neo4jrepositiennesautoconfiguration, / org.springframework.boot.autoconfig ure.data.solr.solrrepositienesAutoconfiguration, / org.springframework.boot.autoconfigure.data.redis.redisautoconfigurati sur, / 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.ellasticsearch.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, / 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. asourceAutoConfiguration, / org.springframework.boot.autoconfigure.jdbc.jdbclateAutoConfiguration, / org.springframewor k.boot.autoconfigure.jdbc.jndatasourceautoconfiguration, / org.springframework.boot.autoconfigure.jdbc.xadatasourceauto Configuration, / org.springframework.boot.autoconfigure.jdbc.datasourcetransactionManageraToConfiguration, / 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.SPRINGFRAMEWROWN.BOOT.AUTOCONFIGURE.JMS.AREMIS.ArtemisAutoConfiguration, / org.springframework.boot.autoconfigure.flyway.flywayautoconfiguration, / org.springframework.boot.autoconfigure.groovy.te Mlate.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.embeddedlapautoconfiguration, / 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.securityfilterautoconfiguration, / org.spri ngframework.boot.autoconfigure.security.fallbackwebsecurityautoconfiguration, / org.springframework.boot.autoconfigure.security.oauth2.oauth2autoconfiguration , / org. springframework.boot.autoconfigure.sse.SessionAutoConfiguration, / org.springframework.boot.autoconfigure.social.socialwaubonfiguration, / org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration, / org.springwork.facebookaut ot.autoconfigure.social.linkedinautoconfiguration, / org.springframework.boot.autoconfigure.social.twitterautoconfigurati sur, / org.springframework.boot.autoconfigure.solr.solrautoconfiguration, / org.springframework.boot.autoconfigure.ThymeaLealeaLeaLealeaLevel .ThyMeleafautoConfiguration, / org.springframework.boot.autoconfigure.transaction.transactionAutoConfiguration, / org.springframework.boot.autoconfigure.transaction.jta.jtaautoconfiguration, / org.springframework. alidationAutoConfiguration,/org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,/org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,/org.springframework.boot.autoconfigure.web.E errormvcautoconfiguration, / org.springframework.boot.autoconfigure.web.httpeCcodingAutoConfiguration, / org.springframewor k.boot.autoconfigure.web.httpmesageconvertersautoconfiguration, / 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.websocketMessageAutoConfiguration, / org.springframework.boot.AutoConfigure.webervices.websvicesAutoConigo analysersorg.springframework.boot.diagnostics.failureanalyzer = / org.springframework.boot.autoconfigure.diagnostics.analyzer.nosuchbeandefinitionfailureanalyzer, / org. springframework.boot.autoconfigure.jdbc.DatasourceBeanCreationFailureanalyzer, / org.springframework.boot.autoconfigure.jdbc.hikaridriverconfigurationfailureanalyzer # Disponibilité du modèle providersorg.springframework.boot.autoconfigure.template.templateavailabilityprovider = / org.springframework.boot.autoconfigure.fre EMARKER.FREEMARKERTEMPLATAVAILIBILITYPROVIDER, / ORG.SpringFramework.boot.AutoConfigure.Mustache.MustachemplateAvailabilityProvi der, / org.springframework.boot.autoconfigure.groovy.template.groovyTemplateavailabilityProvider, / org.springframework.boot.autoConf igure.thymeaf.ThymeaftEmplateavailabilityProvider, / org.springframework.boot.autoconfigure.web.jsplateavailabilityprovider
3) Le filtre filtre filtre les conditions qui ne remplissent pas l'annotation de condition à la condition d'on
Liste privée <string> Filter (list <string> Configurations, autoconfigurationMetadata autoconfigurationMetAdata) {long startTime = System.NanoTime (); String [] candidates = configUrations.toArray (new String [configUrations.size ()]); Boolean [] skip = new Boolean [candidats.length]; booléen sauté = false; // obtient l'intercepteur d'importation de configuration automatique qui doit être filtré, il n'y en a qu'un dans la configuration de Spring.factories: org.springframework.boot.autoconfigure.condition.OnclassCondition pour (autoconfigurationImportFilter Filter: getAutoConfigurationImportFilters ()) {invokeawareMethods (filter); Boolean [] match = filter.match (candidats, autoconfigurationMetAdata); for (int i = 0; i <match.length; i ++) {if (! Match [i]) {skip [i] = true; sauté = true; }}} if (! sauté) {// Tant qu'il y a un décalage -> sauté = true, toutes les correspondances -》 SKINP = false-> return directement aux configurations de retour; } List <string> result = new ArrayList <string> (candidats.length); for (int i = 0; i <candidats.length; i ++) {if (! skip [i]) {// match-》 ne skip-》 ajouter au résultat result.add (candidats [i]); }} if (logger.istraceenabled ()) {int Logger.Trace ("Filtrée" + Numberfiltered + "Classe de configuration automatique dans" + timeunit.nanoseconds.tomillis (System.NanoTime () - StartTime) + "MS"); } return new ArrayList <string> (résultat); }SpringApplication.Run
public configurableApplicationContext run (String ... args) {stopwatch stopwatch = new stopwatch (); stopwatch.start (); ConfigurableApplicationContext context = null; Analyseurs de FailureArAnalysers = NULL; configureHeadlessProperty (); SpringApplicationRunListeners Auditers = GetRunListeners (args); // 1. Obtenez les auditeurs auditeurs.starting (); -> commencez! essayez {applicationArguments applicationArguments = new defaultApplicationArguments (args); Environnement Configurableenvironment = Préparer l'environnement (auditeurs, // 2. Préparez l'environnement et déclenchez l'application environmentPrepareDevent ApplicationArguments); Banner PrintedBanner = printbanner (Environment); // Imprime le caractère de l'invite de démarrage, le diagramme de caractères de ressort par défaut = CreateApplicationContext (); // Instancier un contexte d'application configurable Analysers = new FailLureAlalysers (contexte); prepareContext (contexte, environnement, auditeurs, applicationArguments, // 3. Préparez le contexte imprimébanner); RefreshContext (contexte); // 4. Rafraîchissez le contexte après la réfresh (contexte, applicationArguments); // 5. Après avoir rafraîchi les auditeurs de contexte. stopwatch.stop (); if (this.logStartupInfo) {nouveau startupInfologger (this.mainApplicationClass) .logStarted (getApplicationLog (), stopwatch); } Return Context; } catch (Throwable ex) {handlerunfailure (contexte, auditeurs, analyseurs, ex); jeter un nouvel illégalstateException (ex); }}1. GetRunListeners Get Audivers (SpringApplicationRunListeners)
C'est en fait la classe SpringApplicationRunListener
private SpringApplicationRunListeners getRunListeners (String [] args) {class <?> [] types = new class <?> [] {springApplication.class, String []. class}; Renvoie un nouveau SpringApplicationRunListeners (Logger, GetSpringFactoriesInstances (SpringApplicationRunListener.class, Types, This, Args)); } Private <T> Collection <? étend t> getSpringFactoriesInstances (class <t> type) {return getSpringFactoriesInstances (type, new class <?> [] {}); } Private <T> Collection <? étend t> getSpringFactoriesInstances (class <t> type, class <?> [] ParameterTypes, object ... args) {classloader classloader = thread.currentThread (). getContextClassLoader (); // Utiliser SET pour assurer l'unicité des chaînes set <string> names = new LinkedHashSet <string> (SpringFactoriesLoader.LoadFactoryNames (Type, classloader); // 1. Chargez la collection de noms d'usine <T> Instances = CreateSpringFactoriesInstances (Type, ParameterTypes, // 2. Créer des instances de casse, args, args, noms); AnnotationAwareOrderComparator.sort (instances); // Trier les instances de retour; }1.1 Chargement du nom d'usine (LoadFactoryNames)
Le chargeur de classe de la classe actuelle obtient la configuration de la classe SpringApplicationRunListener à partir du fichier meta-inf / printemps.factories
public static list <string> loadfactoryNames (class <?> factoryClass, classloader classloader) {String factoryClassName = factoryClass.getName (); essayez {énumération <url> urls = (classloader! = null? classloader.getResources (usine_resource_location): classloader.getSystemResources (usine_resource_location)); List <string> result = new ArrayList <string> (); while (urls.hasmoreElements ()) {url url = url.nexttelement (); Properties Properties = PropertiesLoDereUtils.LoadProperties (New UrlResource (URL)); String factoryClassNames = Properties.getProperty (FactoryClassName); result.addall (arrays.aslist (stringUtils.commadelimitedListToStringArray (factoryClassNames))); } Retour Résultat; } catch (ioException ex) {lancez new illégalArgumentException ("Impossible de charger [" + factoryClass.getName () + "] usines de l'emplacement [" + usine_resource_location + "]", ex); }}Dans l'image ci-dessus, après avoir obtenu le nom de la classe d'usine, jetons un coup d'œil à ce qui est défini dans Meta-Inf / Spring.factories:
# PropertySource chargersorg.springframework.boot.env.propertysourceloader = / org.springframework.boot.env.propertiespropertysourceloder, / org.springframework.boot.env.yamlpropertysourceloder # run écouteurs ici, look ici! ! ! ! org.springframework.boot.springApplicationRunListener = / org.springframework.boot.context.event.eventPublishingRunListener # Contexte d'application Initialisersorg.springframework.context.applicationContextInitializer = / org.springframework.boot.context.configurationwarningsapplicationcontextInitializer, / org.springframework.boot.context.contextid,, / org.springframework.boot.context.contextid,, ApplicationContextInitializer, / org.springframework.boot.context.config.delegatingApplicationContexInitializer, / org.springframework.boot.context.embedded.ServerportInfoApplicationContextinitializer # Application # Application # Application # Application # Application # Application # Application # Application # Application # Application # Application # Application Auditersorg.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.configfileApplicationListener, / org.springframework.boot.context.config.delegatingApplicationListener, / org.springframework.boot.liquibase.liqui BaseServiceLocatorApplicationListener, / org.springframework.boot.logging.classpathloggingApplicationListener, / org.springframework.boot.logging.loggingApplicationListener # Environment Post Processorsorg.springframework.boot.env.EnvironmentPostProcessor=/org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,/org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor# Failure Analysersorg.springframework.boot.diagnostics.failureanalyzer = / org.springframework.boot.diagnostics.analyzer.beancurrently incerofaWereanalyzer, / org. springframework.boot.diagnostics.analyzer.beannotofrequiredTypefailureanalyzer, / org.springframework.boot.diagnostics.analyzer.bindfailureanalyzer, / org.spr ingframework.boot.diagnostics.analyzer.connectorstartfailureanalyzer, / org.springframework.boot.diagnostics.analyzer.NouniqueBeAndefinitionFaireanalyzer, /org.springframework.boot.diagnostics.analyzer.portinusefailureanalyzer ,/org.springframework.boot.diagnostics.analyzer.validationxceptionfailureanalyzer# FaillureanalysisReportersorg.springframework.boot.diagnostics.failureanalysisreporter = / org.springframework.boot.diagnostics.loggingfailureanalyseporter
Wow, toutes ces classes ont des noms complets, et les clés sont des interfaces, et les valeurs sont des classes d'implémentation. Nous obtenons la classe d'implémentation Value = "org.springFramework.boot.springApplicationRunListener" Requête basée sur la version de l'événement KEY = "org.springframework.boot.context.event.eventpublishingrunListener" et démarrez l'auditeur. Une fois que vous devinez, vous devez utiliser "Réflexion" pour obtenir l'instance de classe en fonction du nom de classe. Ce qui suit est rapidement vérifié ...
1.2 Créer des instances d'usine de printemps
Générer une instance d'usine "EventPublishing Start Average" basée sur les noms Set <string> (la seule classe d'implémentation EventPublishingRunListener de SpringApplicationRunListener) obtenue dans la première étape
@SuppressWarnings ("Unchecked") Private <T> List <T> CREATESPRINGFACTORYSINSTANCES (classe <T> Type, Class <?> [] ParamètreTypes, Classloader Classloader, objet [] args, set <string> noms) {list <t> instances = new ArrayList <T> (noms.Size ()); for (String name: names) {try {class <?> instanceClass = classutils.forname (name, classloader); // utilise la réflexion pour obtenir la classe affirmer.issignable (type, instanceClass); Constructor <?> Constructor = instanceClass .getDeclaredConstructor (ParameterTypes); // Obtenez le constructeur t instance = (t) beanutils.InstantiateClass (constructeur, args); // construire des instances basées sur le constructeur et les paramètres Instances.Add (instance); } catch (Throwable ex) {Throw New illégalArgumentException ("Impossible d'instancier" + type + ":" + name, ex); }} retour des instances; }Préparer le contexte
Private void PrepareContext (ConfigurableApplicationContext Context, configurableenvironment, SpringApplicationRunSteners Auditeurs, applicationArguments ApplicationArguments, bannière imprimébanner) {context.Settenirvironment (environnement); PostProcessApplicationContext (contexte); // singleton a beannamegenerator, définissez le ResourceLoader dans le contexte de l'application ApplicationInitialisers (context); // exécuter les auditeurs initialiseurs.ContextPrepared (contexte); // LOUDER EXECUTUTION CONTEXT "PRÉPETED" Method if (this.logstartupinfo) {LOGSTARTUPINFOFO (ContextPaRent () ==) {LogStartupinfo (ContextPaRent () ==) {LogStarTupinfo (ContextPaRent () ==); LogStartupprofileInfo (contexte); } // Ajouter Spring Boot Special Singleton Bean Context.getBeanFactory (). Registersingleton ("SpringApplicationArguments", applicationArguments); if (imprimébanner! = null) {context.getBeanFactory (). Registersingleton ("Springbootbanner", imprimébanner); } // Chargez le jeu de ressources <objet> sources = getSources (); Affirmer.notempty (sources, «les sources ne doivent pas être vides»); charge (contexte, sources.toArray (nouvel objet [sources.size ()])); écouteursActualiser le contexte
Private void RefreshContext (ConfigurableApplicationContext Context) {Refresh (context); // Core classe if (this.registershutdownhook) {try {context.registershutdownhook (); // enregistrer le crochet de clôture, exécuter dans certains environnements fermés. }}} Protected void Refresh (ApplicationContext ApplicationContext) {Asssert.IsinstanceOf (AbstractApplicationContext.class, applicationContext); ((AbstractApplicationContext) ApplicationContext) .Refresh (); }L'exécution finale est la méthode de rafraîchissement de la classe abstraite abstraiteContext.
Public Void Refresh () lève la conception de BeanSexception, illégalStateException {synchronisé (this.startupShutdownmonitor) {// prépare à actualiser l'environnement de contexte, tel que la préparation et la vérification des propriétés du système ou des variables d'environnement. preparereFresh (); // Démarrez la méthode RafreshbeanFactory de la sous-classe. Parses XML ConfigurableLlistableBeAnfactory Beanfactory = GetSFreshBeanFactory (); // Configurez les fonctionnalités des conteneurs pour le beanfactory, telles que le chargeur de classe, le gestionnaire d'événements, etc. PrepareBeAnfactory (beanfactory); Essayez {// Définissez le post-traitement du Beanfactory. Méthode vide, laissez-le pour l'expansion de la sous-classe. PostprocessBeanFactory (Beanfactory); // Appelez les postprocesseurs de Beanfactory, qui sont enregistrés auprès du conteneur dans la définition du bean. InvokeBeanFactoryPostProcessors (Beanfactory); // Enregistrez le post-processeur du haricot et appelez-le pendant le processus de création de haricots. RegisterBeanPostProcessors (BeanFactory); // Initialisez la source de message dans le contexte, c'est-à-dire que les corps de message dans différentes langues sont traités à l'international initMessagesource (); // Initialisez le Bean ApplicationEventMulticaster, et le diffuseur de l'événement d'application est initApplicationEventMulticaster (); // Initialisez d'autres haricots spéciaux, des méthodes vides et les laisser pour l'expansion de la sous-classe. onRefresh (); // Vérifiez et enregistrez l'écouteur RegisterListeners (); // Instance Tous les haricots singleton restants (non-paresseux). FinishBeanFactoryInitialisation (Beanfactory); // Publier des événements de conteneurs et terminer le processus de rafraîchissement. fini finalRefresh (); } catch (beanSexception ex) {if (logger.iswarneNabled ()) {logger.warn ("Exception rencontrée lors de l'initialisation du contexte -" + "Annulation de rafraîchissement de la tentative:" + ex); } // Détruisez le haricot Singleton créé pour éviter la consommation de ressources. Destroybeans (); // Annuler l'opération de rafraîchissement et réinitialiser l'indicateur actif. CancelRefresh (ex); // propager l'exception à l'appelant. jeter ex; } Enfin {// Réinitialiser le cache de base de Spring ResetCommonCaches (); }}}Après avoir rafraîchi le contexte
Spring Boot fournit deux interfaces pour que les utilisateurs se développent eux-mêmes: ApplicationRunner et CommandLinerUnner. Vous pouvez effectuer des opérations similaires à l'initialisation des données après le démarrage du conteneur (une fois le contexte actualisé).
CallRunners void privé (contexte ApplicationContext, applicationArguments args) {list <object> coureners = new ArrayList <Bject> (); Runners.addall (context.getBeansofType (applicationRunner.class) .Values ()); // getall of type applicationRunner de the context coureners.addall (context.getBeansofType (commandlinerunner.class) .values ()); // getall de type commandliner pour le contexte annotationware. (Object Runner: New LinkedHashSet <Bject> (Runners)) {if (Runner instanceof applicationRunner) {callRunner ((applicationRunner) Runner, args); // Execute} if (Runner instanceOf CommandLinerUnner) {callRunner ((CommandLinerUner) Runner, args); }}}Les deux différences sont que les paramètres sont différents, alors choisissez par vous-même en fonction de la situation réelle.
Interface publique CommandLinerUnner {void run (string ... args) lève une exception; } Interface publique ApplicationRunner {void run (applicationArguments args) lève une exception; }Les paramètres d'exécution dans CommandLinerUnner sont les paramètres de tableau de chaîne String [] Args de la méthode principale de la classe de démarrage Java d'origine; Les paramètres dans ApplicationRunner sont traités pour fournir certaines méthodes telles que:
List <string> getOptionValues (nom de chaîne);
Obtenez la liste des valeurs en fonction du nom, dans la commande de démarrage Java --Foo = Bar --Foo = Baz, puis la liste de retour ["bar", "baz"] selon le nom du paramètre FOO
Selon l'analyse précédente, le processus de démarrage du conteneur de Spring-Boot peut être divisé en 2 parties:
1) Annotation d'exécution: scanner les beans sous la plage spécifiée, charger les haricots correspondant à la classe de configuration automatique et les charger dans le conteneur IOC.
2) Le SpringAppliocation spécifique.
ApplicationFaileEvent.classApplicationPrepareDevent.classApplicationreadyEvent.classApplicationStartDevent.classApplicationStartInEvent.ClasssPringApplicationEvent.class
Ici, nous utilisons le modèle classique du printemps, Ticket Air: Modèle et modèle d'observateur axés sur les événements printaniers
Le diagramme de classe est le suivant:
Comme indiqué dans l'image ci-dessus, il s'agit d'un modèle classique axé sur les événements de printemps, y compris 3 rôles: éditeur d'événements, événement et auditeur. Correspondant à Spring-Boot est:
1.EventpublishingrunRistener Cette classe résume la publication d'événements,
2. SpringApplicationEvent est un événement défini dans Spring-Boot (les 6 événements mentionnés ci-dessus), hérités de ApplicationEvent (défini au printemps)
3. Écouteur Spring-Boot n'implémente pas l'auditeur pour les 6 événements ci-dessus (je n'ai pas trouvé ...). 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时,如果启动没有异常,就会执行!可以做一些数据初始化之类的操作。
Résumer
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. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!