Análise do processo de inicialização do SpringBoot

SpringBoot -  classe de inicialização padrão spring.factories

# PropertySource Loaders

org.springframework.boot.env.PropertySourceLoader = \

org.springframework.boot.env.PropertiesPropertySourceLoader, \

org.springframework.boot.env.YamlPropertySourceLoader

 

# Executar ouvintes

org.springframework.boot.SpringApplicationRunListener = \

org.springframework.boot.context.event.EventPublishingRunListener

 

# Error Reporters

org.springframework.boot.SpringBootExceptionReporter = \

org.springframework.boot.diagnostics.FailureAnalyzers

 

# Inicializadores de contexto de aplicativo

org.springframework.context.ApplicationContextInitializer = \

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer, \

org.springframework.boot.context.ContextIdApplicationContextInitializer, \

org.springframework.boot.context.config.DelegatingApplicationContextInitializer, \

org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

 

# Ouvintes de aplicativos

org.springframework.context.ApplicationListener = \

org.springframework.boot.ClearCachesApplicationListener, \

org.springframework.boot.builder.ParentContextCloserApplicationListener, \

org.springframework.boot.context.FileEncodingApplicationListener, \

org.springframework.boot.context.config.AnsiOutputApplicationListener, \

org.springframework.boot.context.config.ConfigFileApplicationListener, \

org.springframework.boot.context.config.DelegatingApplicationListener, \

org.springframework.boot.context.logging.ClasspathLoggingApplicationListener, \

org.springframework.boot.context.logging.LoggingApplicationListener, \

org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

 

# Ambiente pós-processadores

org.springframework.boot.env.EnvironmentPostProcessor = \

org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor, \

org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor, \

org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor

 

# Analisadores de falha

org.springframework.boot.diagnostics.FailureAnalyzer = \

org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer, \

org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer

 

# FailureAnalysisReporters

org.springframework.boot.diagnostics.FailureAnalysisReporter = \

org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

 

Análise do processo SpringBoot-start

http://blog.csdn.net/doegoo/article/details/52471310

https://www.processon.com/special/template/5d9f1a26e4b06b7d6ec5cfd4

1. Inicialize SpringApplication

new SpringApplication (primarySources) .run (args);

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	this.webApplicationType = deduceWebApplicationType();
	setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
	setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class));
	this.mainApplicationClass = deduceMainApplicationClass();
}

Obtenha todos os ApplicationContextInitializer e ApplicationListener

1. SpringFactoriesLoader.loadFactoryNames (type, classLoader));

2. createSpringFactoriesInstances (type, parameterTypes, classLoader, args, names);

// Carrega FactoryNames do local especificado META-INF / spring.factories

 

2. Execute o método run ()

	/**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
        // getSpringFactoriesInstances 从 spring.factories 加载
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			listeners.started(context);
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, exceptionReporters, ex);
			throw new IllegalStateException(ex);
		}
		listeners.running(context);
		return context;
	}

1.SpringApplicationRunListeners listeners = getRunListeners (args);

listeners.starting (); // Aciona o evento ApplicationStartingEvent

// A interface SpringApplicationRunListener especifica o ciclo de vida da inicialização, transmite eventos correspondentes em cada ciclo de vida e chama o ApplicationListener real

 

2.ConfigurableEnvironment environment = prepareEnvironment (listeners, applicationArguments)

a> getOrCreateEnvironment ();

// Crie um ambiente padrão

 

b> configureEnvironment (environment, applicationArguments.getSourceArgs ());

// Vinculando CommandLinePropertySource para obter parâmetros de linha de comando

// 绑定 Perfil environment.setActiveProfiles (StringUtils.toStringArray (profiles)); 指定 ActiveProfile

 

c> listeners.environmentPrepared (ambiente); // 触发 EnvironmentPrepared 事件

ConfigFileApplicationListener é um ouvinte para processar arquivos de configuração no Spring Boot

1. Obtenha todos os EnvironmentPostProcessor após ouvir onApplicationEnvironmentPreparedEvent e execute o método postProcessEnvironment

2. Carregue o arquivo de configuração do Spring após distinguir o perfil em seu próprio método postProcessEnvironment

3. Adicione PropertySourceOrderingPostProcessor implementa BeanFactoryPostProcessor após ouvir onApplicationEnvironmentPreparedEvent

 

3.createApplicationContext ();

// 实例 化 AnnotationConfigServletWebServerApplicationContext || AnnotationConfigApplicationContext

public class AnnotationConfigServletWebServerApplicationContext

estende ServletWebServerApplicationContext implementa AnnotationConfigRegistry

 

Implementação do método de construção padrão da classe pai

public GenericApplicationContext () {

this.beanFactory = novo DefaultListableBeanFactory ();

}

 

4.prepareContext (contexto, ambiente, ouvintes, argumentos do aplicativo ,printBanner)

a> context.setEnvironment (environment);

 

b> postProcessApplicationContext (contexto);

// 注册 BeanNameGenerator AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR

 

c> applyInitializers (contexto);

// Chame o método de inicialização ApplicationContextInitializer..initialize (contexto)

 

d> listeners.contextPrepared (context); // método vazio

 

e> load (context, sources.toArray (new Object [0]));

// Pegue a fonte, a classe principal, como um bean e carregue-a no contêiner de primavera

[classe com.liuwei.springboot.MybatisApplication]

 

f> listeners.contextLoaded (context); // disparar o evento ApplicationPreparedEvent

 

5.1 refreshContext (contexto);

https://www.jianshu.com/p/a0a5088a651d?utm_campaign=hugo

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

https://www.jianshu.com/p/a0a5088a651d?utm_campaign=hugo

https://www.cnblogs.com/disandafeier/p/12081301.html

// Prepare este contexto para atualização.

(1) prepareRefresh ();

Inicializar marcadores de posição no ambiente de contexto

Prepare e verifique as variáveis ​​de ambiente do sistema ou atributos do sistema

 

// Diga à subclasse para atualizar a fábrica de bean interna.

(2) ConfigurableListableBeanFactory beanFactory = getFreshBeanFactory ();

this.beanFactory = new DefaultListableBeanFactory (); // Criar e inicializar beanFactory

 

// Prepare a fábrica de feijão para uso neste contexto.

(3) prepareBeanFactory (beanFactory);

// Preencha várias funções de BeanFactory, como anotações comumente usadas @Autowired @Qualifier, etc.

 

// Define o analisador da expressão SPEL # {key}

beanFactory.setBeanExpressionResolver (novo StandardBeanExpressionResolver (beanFactory.getBeanClassLoader ()));

 

// Configure o registro do editor de recursos, como suporte para PerpertyEditorSupper

beanFactory.addPropertyEditorRegistrar (new ResourceEditorRegistrar (this, getEnvironment ()));

 

// Adicionar processador ApplicationContextAwareProcessor

beanFactory.addBeanPostProcessor (novo ApplicationContextAwareProcessor (this));

 

// Ignora a implementação da interface * Aware na injeção de dependência, beanFactory.ignoreDependencyInterface, como EnvironmentAware, ApplicationEventPublisherAware, ApplicationContextAware, ResourceLoaderAware, EmbeddedValueResolverAware, MessageSourceAware, etc.

// Auto-montagem ignorada (ou seja, os beans que implementam essas interfaces, não conectam automaticamente com Autowired)

 

// Dependência de registro, se uma propriedade de bean contiver ApplicationEventPublisher (beanFactory), uma instância de beanFactory será injetada nele

beanFactory.addBeanPostProcessor (novo ApplicationListenerDetector (this));

 

// Injetar alguns outros beans de informação, como environment, systemProperties, SystemEnvironment, etc.

 

// Permite o pós-processamento da fábrica de feijão em subclasses de contexto.

(4) postProcessBeanFactory (beanFactory);

https://fangjian0423.github.io/2017/05/10/springboot-context-refresh/

beanFactory.addBeanPostProcessor (

new WebApplicationContextServletContextAwareProcessor (this));

O contêiner GenericWebApplicationContext adicionará um ServletContextAwareProcessor ao BeanFactory para chamar setServletContext ao processar a inicialização do bean de tipo ServletContextAware

 

// Chama os processadores de fábrica registrados como beans no contexto.

(5) invokeBeanFactoryPostProcessors (beanFactory);

Descubra todos os beans no beanFactory que implementam a interface BeanDefinitionRegistryPostProcessor e a interface BeanFactoryPostProcessor

Coloque todos os beans do programa em beanDefinitionMap. Observe que esta etapa não instancia o bean, mas obtém o beanDefinition do bean

 

// Registra processadores de bean que interceptam a criação de bean.

(6) registerBeanPostProcessors (beanFactory);

Encontre a implementação de BeanPostProcessor, registre-a no contêiner após a classificação

// Inicializa a fonte da mensagem para este contexto.

(7) initMessageSource ();

Inicializar propriedades relacionadas à internacionalização

 

// Inicializa o multicaster de eventos para este contexto.

(8) initApplicationEventMulticaster ();

Inicialize o transmissor do evento

 

// Inicializa outros beans especiais em subclasses de contexto específicas.

(9) onRefresh ();

createWebServer (); // Criar um contêiner da web

 

// Verifique os beans listener e registre-os.

(10) registerListeners ();

 

// Instancie todos os singletons restantes (não-lazy-init).

(11) terminarBeanFactoryInitialization (beanFactory);

Instancie todos os beans não preguiçosos em beanDefinitionMap

// O processo de instanciação do bean spring https://www.cnblogs.com/kevin-yuan/p/12157017.html

 

// Última etapa: publicar o evento correspondente.

(12) terminarRefresh ();

 

// Reinicia caches de introspecção comuns no núcleo do Spring, já que nós

// pode não precisar mais de metadados para beans singleton ...

(13) resetCommonCaches ();

 

5.2 registerShutdownHook ()

 

6.afterRefresh (context, applicationArguments); // método vazio

 

7.listeners.started (context); // acionar o evento ApplicationStartedEvent

 

8.callRunners (contexto, argumentos de aplicação);

// 执行 ApplicationRunner e CommandLineRunner

 

9.listeners.running (context); // Aciona o evento ApplicationReadyEvent

 

 Mecanismo de evento de inicialização de aplicativo

ApplicationContextInitializer

Se realmente precisarmos personalizar um ApplicationContextInitializer, configure-o por meio do mecanismo SpringFactoriesLoader ou defina-o por meio de SpringApplication.addInitializer (..)

 

ApplicationListener (quatro tipos de eventos suportados)

ApplicationStartedEvent :: um evento executado quando a inicialização do Spring começa

ApplicationEnvironmentPreparedEvent: O ambiente correspondente do Spring boot foi preparado, mas o contexto ainda não foi criado.

ApplicationPreparedEvent: O contexto de inicialização da primavera é criado, mas os beans na primavera não estão totalmente carregados neste momento

ApplicationFailedEvent: evento de execução quando a inicialização da mola começa de forma anormal 

Se quisermos adicionar um ApplicationListener personalizado ao aplicativo SpringBoot, existem duas maneiras:

1) Adicione um ou mais ApplicationListeners personalizados por meio do método SpringApplication.addListeners (..) ou SpringApplication.setListeners (..);

2) Com a ajuda do mecanismo SpringFactoriesLoader, adicione a configuração no arquivo META-INF / spring.factories

 

EnvironmentPostProcessor

BeanPostProcessor

BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor

Consciente

 

@Configuration 和 Auto-configuração

Todas são classes anotadas com @Configuration e @Bean , @Import , @ImportResource podem ser definidas nessas classes .

Você pode usar @ Condition * para escolher se deseja carregar de acordo com a situação

 

AnnotatedBeanDefinitionReader

ConfigurationClassPostProcessor

ConfigurationClassParser

EnableAutoConfigurationImportSelector

 

Descrição de classe integrada

LoggingApplicationListener

LoggingApplicationListener é usado para configurar o sistema de registro, como logback e log4j.

 

Ambiente Padrão

StandardEnvironment tem um MutablePropertySources , que tem vários PropertySources . PropertySource é responsável por fornecer propriedades (isto é, a fonte da propriedade). Implementações de PropertySource atualmente conhecidas são: MapPropertySource , SystemEnvironmentPropertySource , CommandLinePropertySource, etc.

No projeto real, se as informações de recursos podem ser obtidas dinamicamente ao modificar a configuração do produto online, é muito conveniente, o seguinte mostra um caso de carregamento de recursos obtidos dinamicamente, em vez de carregar informações de arquivo de propriedades embutidas em código

Primeiro, construa PropertySource e, em seguida, adicione-o ao Environment

 

ConfigFileApplicationListener

ConfigFileApplicationListener é usado para carregar application.properties no StandardEnvironment .

ConfigFileApplicationListener usa internamente EnvironmentPostProcessor (

 

ApplicationContextAwareProcessor

  1. EnvironmentAware
  2. EmbeddedValueResolverAware
  3. ResourceLoaderAware

 

  1. ApplicationEventPublisherAware
  2. MessageSourceAware
  3. ApplicationContextAware

 

AnnotationConfigApplicationContext

AnnotatedBeanDefinitionReader

 

Um, @ Enable * anotação

As anotações @ Enable * não são anotações inventadas recentemente.Essas anotações foram introduzidas já na estrutura do Spring 3, e essas anotações são usadas para substituir arquivos de configuração XML.

Muitos desenvolvedores Spring conhecem a anotação @EnableTransactionManagement, que pode declarar o gerenciamento de transações; a anotação @EnableWebMvc, que pode ativar Spring MVC; e a anotação @EnableScheduling, que pode inicializar um planejador.

Essas anotações são, na verdade, configurações simples, importadas por meio de anotações @Import.

 

dois,

O Spring  boot suporta arquivos de configuração em dois formatos por padrão: .properties.yml.

Spring Boot também fornece um método de configuração de tipo seguro, que associa a propriedade properties a um Bean e suas propriedades por meio de @ConfigurationProperties para obter a configuração de tipo seguro

@ConfigurationProperties (prefixo = "usuário")

 

 

Configuração de três perfis

Perfil é usado pelo Spring para fornecer suporte para diferentes configurações para diferentes ambientes. A configuração de Perfil Global é usada

application- {profile} .properties 如: application-prod.properties

 

 

 

 

Acho que você gosta

Origin blog.csdn.net/lewee0215/article/details/111828975
Recomendado
Clasificación