SpringBoot: clase de inicio predeterminada spring.factories
# Cargadores PropertySource
org.springframework.boot.env.PropertySourceLoader = \
org.springframework.boot.env.PropertiesPropertySourceLoader, \
org.springframework.boot.env.YamlPropertySourceLoader
# Ejecutar oyentes
org.springframework.boot.SpringApplicationRunListener = \
org.springframework.boot.context.event.EventPublishingRunListener
# Reporteros de errores
org.springframework.boot.SpringBootExceptionReporter = \
org.springframework.boot.diagnostics.FailureAnalyzers
# Inicializadores de contexto de aplicación
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
# De oyentes de aplicaciones
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
# Postprocesadores ambientales
org.springframework.boot.env.EnvironmentPostProcessor = \
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor, \
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor, \
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
# Analizadores de fallas
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álisis del proceso SpringBoot-start
http://blog.csdn.net/doegoo/article/details/52471310
https://www.processon.com/special/template/5d9f1a26e4b06b7d6ec5cfd4
1. Inicializar SpringApplication
new SpringApplication (fuentes primarias) .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();
}
Obtenga todos los ApplicationContextInitializer y ApplicationListener
1. SpringFactoriesLoader.loadFactoryNames (tipo, classLoader));
2. createSpringFactoriesInstances (tipo, parameterTypes, classLoader, argumentos, nombres);
// Cargue FactoryNames desde la ubicación especificada META-INF / spring.factories
2. Ejecute el 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 oyentes = getRunListeners (argumentos);
listeners.starting (); // Activa el evento ApplicationStartingEvent
// La interfaz SpringApplicationRunListener especifica el ciclo de vida de Boot, transmite los eventos correspondientes en cada ciclo de vida y llama al ApplicationListener real
Entorno 2.ConfigurableEnvironment = prepareEnvironment (oyentes, argumentos de la aplicación)
a> getOrCreateEnvironment ();
// Crea un entorno estándar
b> configureEnvironment (entorno, applicationArguments.getSourceArgs ());
// Vincular CommandLinePropertySource para obtener parámetros de línea de comando
// 绑定 Perfil environment.setActiveProfiles (StringUtils.toStringArray (perfiles)); 指定 ActiveProfile
c> listeners.environmentPrepared (entorno); // 触发 EnvironmentPrepared 事件
ConfigFileApplicationListener es un oyente para procesar archivos de configuración en Spring Boot
1. Obtenga todos los EnvironmentPostProcessor después de escuchar enApplicationEnvironmentPreparedEvent y ejecute el método postProcessEnvironment
2. Cargue el archivo de configuración de Spring después de distinguir el perfil en su propio método postProcessEnvironment
3. Agregue PropertySourceOrderingPostProcessor implementa BeanFactoryPostProcessor después de escuchar enApplicationEnvironmentPreparedEvent
3.createApplicationContext ();
// 实例 化 AnnotationConfigServletWebServerApplicationContext || AnnotationConfigApplicationContext
clase pública AnnotationConfigServletWebServerApplicationContext
extiende ServletWebServerApplicationContext implementa AnnotationConfigRegistry
Implementación del método de construcción predeterminado de la clase principal
public GenericApplicationContext () {
this.beanFactory = new DefaultListableBeanFactory ();
}
4.prepareContext (contexto, entorno, oyentes, applicationArguments, PrintedBanner)
a> context.setEnvironment (entorno);
b> postProcessApplicationContext (contexto);
// 注册 BeanNameGenerator AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR
c> applyInitializers (contexto);
// Llamar al método de inicialización ApplicationContextInitializer..initialize (context)
d> listeners.contextPrepared (context); // método vacío
e> load (context, sources.toArray (new Object [0]));
// Toma la fuente, la clase principal, como un bean y cárgala en el contenedor de primavera
[clase com.liuwei.springboot.MybatisApplication]
f> listeners.contextLoaded (context); // desencadena el 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
// Prepara este contexto para actualizar.
(1) prepareRefresh();
Inicializar marcadores de posición en el entorno de contexto
Preparar y verificar las variables de entorno del sistema o los atributos del sistema.
// Dile a la subclase que actualice la fábrica de beans interna.
(2) ConfigurableListableBeanFactory beanFactory = getFreshBeanFactory ();
this.beanFactory = new DefaultListableBeanFactory (); // Crear e inicializar beanFactory
// Prepare la fábrica de frijoles para su uso en este contexto.
(3) prepareBeanFactory (beanFactory);
// Complete varias funciones de BeanFactory, como las anotaciones de uso común @Autowired @Qualifier, etc.
// Establecer el analizador de la expresión SPEL # {clave}
beanFactory.setBeanExpressionResolver (nuevo StandardBeanExpressionResolver (beanFactory.getBeanClassLoader ()));
// Configurar el registro del editor de recursos, como el soporte de PerpertyEditorSupper
beanFactory.addPropertyEditorRegistrar (nuevo ResourceEditorRegistrar (esto, getEnvironment ()));
// Agregar procesador ApplicationContextAwareProcessor
beanFactory.addBeanPostProcessor (nuevo ApplicationContextAwareProcessor (esto));
// Ignore la implementación de la interfaz * Aware en la inyección de dependencias, beanFactory.ignoreDependencyInterface como EnvironmentAware, ApplicationEventPublisherAware, ApplicationContextAware, ResourceLoaderAware, EmbeddedValueResolverAware, MessageSourceAware, etc.
// Autoensamblaje ignorado (es decir, beans que implementan estas interfaces, no auto-cablean Autowired)
// Dependencia de registro, si una propiedad de bean contiene ApplicationEventPublisher (beanFactory), se inyectará una instancia de beanFactory
beanFactory.addBeanPostProcessor (nuevo ApplicationListenerDetector (esto));
// Inyecta otros beans de información, como entorno, propiedades del sistema, entorno del sistema, etc.
// Permite el posprocesamiento de la fábrica de frijoles en subclases de contexto.
(4) postProcessBeanFactory (beanFactory);
https://fangjian0423.github.io/2017/05/10/springboot-context-refresh/
beanFactory.addBeanPostProcessor (
new WebApplicationContextServletContextAwareProcessor (esto));
El contenedor GenericWebApplicationContext agregará un ServletContextAwareProcessor a BeanFactory para llamar a setServletContext al procesar la inicialización del bean de tipo ServletContextAware
// Invocar procesadores de fábrica registrados como beans en el contexto.
(5) invokeBeanFactoryPostProcessors (beanFactory);
Descubra todos los beans en beanFactory que implementan la interfaz BeanDefinitionRegistryPostProcessor y la interfaz BeanFactoryPostProcessor
Coloque todos los beans del programa en beanDefinitionMap. Tenga en cuenta que este paso no crea una instancia del bean, sino que obtiene el beanDefinition del bean.
// Registra los procesadores de beans que interceptan la creación de beans.
(6) registerBeanPostProcessors (beanFactory);
Encuentre la implementación de BeanPostProcessor, regístrelo en el contenedor después de ordenar
// Inicializa la fuente del mensaje para este contexto.
(7) initMessageSource ();
Inicializar propiedades relacionadas con la internacionalización
// Inicializa el evento multicaster para este contexto.
(8) initApplicationEventMulticaster ();
Inicializar la emisora de eventos
// Inicializa otros beans especiales en subclases de contexto específicas.
(9) onRefresh ();
createWebServer (); // Crea un contenedor web
// Busque beans de escucha y regístrelos.
(10) registerListeners ();
// Crea una instancia de todos los singleton restantes (non-lazy-init).
(11) finishBeanFactoryInitialization (beanFactory);
Crear una instancia de todos los beans no perezosos en beanDefinitionMap
// El proceso de instanciación de spring bean https://www.cnblogs.com/kevin-yuan/p/12157017.html
// Último paso: publicar el evento correspondiente.
(12) finishRefresh ();
// Restablece los cachés de introspección comunes en el núcleo de Spring, ya que
// puede que ya no necesite metadatos para los beans singleton ...
(13) resetCommonCaches ();
5.2 registerShutdownHook ()
6.afterRefresh (context, applicationArguments); // método vacío
7.listeners.started (contexto); // desencadena el evento ApplicationStartedEvent
8.callRunners (contexto, applicationArguments);
// 执行 ApplicationRunner y CommandLineRunner
9.Listeners.running (context); // Activa el evento ApplicationReadyEvent
Mecanismo de evento de inicio de la aplicación
ApplicationContextInitializer
Si realmente necesitamos personalizar un ApplicationContextInitializer, configúrelo mediante el mecanismo SpringFactoriesLoader, o configúrelo mediante SpringApplication.addInitializers (..)
ApplicationListener (cuatro tipos de eventos admitidos)
ApplicationStartedEvent :: un evento ejecutado cuando comienza el arranque de primavera
ApplicationEnvironmentPreparedEvent: Se ha preparado el entorno correspondiente de Spring Boot, pero el contexto aún no se ha creado.
ApplicationPreparedEvent: se crea el contexto de arranque de primavera, pero los beans en primavera no están completamente cargados en este momento
ApplicationFailedEvent: evento de ejecución cuando el arranque de primavera se inicia de forma anormal
Si queremos agregar un ApplicationListener personalizado a la aplicación SpringBoot, hay dos formas:
1) Agregue uno o más ApplicationListeners personalizados a través del método SpringApplication.addListeners (..) o SpringApplication.setListeners (..);
2) Con la ayuda del mecanismo SpringFactoriesLoader, agregue la configuración en el archivo META-INF / spring.factories
EnvironmentPostProcessor
BeanPostProcessor
BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor
Consciente
@Configuration 和 Autoconfiguración
Todas son clases anotadas con @Configuration , y @Bean , @Import , @ImportResource se pueden definir en estas clases .
Puede usar @ Condición * para elegir si se carga según la situación
AnnotatedBeanDefinitionReader
ConfigurationClassPostProcessor
ConfigurationClassParser
EnableAutoConfigurationImportSelector
Descripción de clase incorporada
LoggingApplicationListener
LoggingApplicationListener se utiliza para configurar el sistema de registro, como logback y log4j.
Entorno estándar
StandardEnvironment tiene un MutablePropertySources , que tiene múltiples PropertySources . PropertySource es responsable de proporcionar propiedades (es decir, el origen de la propiedad) actualmente conocidas. PropertySource implementaciones son: MapPropertySource , SystemEnvironmentPropertySource , CommandLinePropertySource, etc.
En el proyecto real, si la información del recurso se puede obtener dinámicamente al modificar la configuración del producto en línea, es muy conveniente, a continuación se muestra un caso de carga de recursos obtenidos dinámicamente, en lugar de cargar información de archivo de propiedades codificada de forma rígida
Primero construya PropertySource y luego agréguelo al Environment
ConfigFileApplicationListener
ConfigFileApplicationListener se utiliza para cargar application.properties en StandardEnvironment .
ConfigFileApplicationListener utiliza internamente EnvironmentPostProcessor (
ApplicationContextAwareProcessor
AnnotationConfigApplicationContext
AnnotatedBeanDefinitionReader
Uno, @ Habilitar * anotación
Las anotaciones @ Enable * no son anotaciones recién inventadas. Estas anotaciones se introdujeron ya en el marco de Spring 3, y estas anotaciones se utilizan para reemplazar los archivos de configuración XML.
Muchos desarrolladores de Spring conocen la anotación @EnableTransactionManagement, que puede declarar la administración de transacciones; la anotación @EnableWebMvc, que puede habilitar Spring MVC; y la anotación @EnableScheduling, que puede inicializar un programador.
Estas anotaciones son en realidad configuraciones simples, importadas a través de anotaciones @Import.
dos,
Spring boot admite archivos de configuración en dos formatos por defecto: .properties.yml.
Spring Boot también proporciona un método de configuración de tipo seguro, que asocia la propiedad de propiedades con un Bean y sus propiedades a través de @ConfigurationProperties para lograr una configuración de tipo seguro.
@ConfigurationProperties (prefijo = "usuario")
Configuración de tres perfiles
Spring utiliza el perfil para proporcionar soporte para diferentes configuraciones para diferentes entornos. Se utiliza la configuración de perfil global
application- {profile} .properties 如: application-prod.properties