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
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