Red de conocimiento informático - Problemas con los teléfonos móviles - El principio de lectura de archivos de configuración de Springboot

El principio de lectura de archivos de configuración de Springboot

El proceso de lectura de archivos de configuración de Springboot (application.yaml, application.properties) ocurre en la etapa SpringApplication#prepareEnvironment(), y prepareEnvironment pertenece a la primera etapa de todo el inicio de la aplicación Springboot. La preparación del entorno es la base para la creación de beans posteriores. Al eliminar el código de StopWatch, puede ver que prepareEnvironment ocurre durante la fase de ejecución de SpringApplication#, que es prácticamente el primer paso de un proceso de varios pasos que inicia toda la aplicación.

La parte más importante de prepareEnvironment es SimpleApplicationEventMulticaster#multicastEvent, que se activa mediante un oyente (EventPublishingRunListener).

La implementación de SimpleApplicationEventMulticaster#multicastEvent es realmente muy simple. Encuentre los oyentes relevantes ApplicationEnvironmentPreparedEvent y luego llame a sus métodos Listener#onApplicationEvent (evento) uno por uno, incluidos los oyentes de procesamiento de archivos de configuración.

Antes de Springboot 2.4.0, el escucha del archivo de configuración era ConfigFileApplicationListener, y después de 2.4.0, el escucha del archivo de configuración era EnvironmentPostProcessorApplicationListener, y el método de carga de los archivos de configuración también ha cambiado mucho, lo que hace posible Leading a algunos cambios de comportamiento, que es lo que discutiremos en detalle a continuación.

Después de Springboot 2.4.0, el orden de carga de los archivos de configuración es el siguiente según la prioridad (el que tenga el número de serie mayor será sobrescrito por el más pequeño):

Comparado con la versión anterior, el orden general de carga de propiedades no se ajusta, solo se cambia el orden de las propiedades de la aplicación (14, 15):

Si hay varios perfiles activos, como [Prueba, Desarrollo] Luego, para dos perfiles, la configuración en el último archivo de configuración (desarrollo) sobrescribirá los valores de configuración en el archivo de configuración anterior (prueba).

Dicho todo esto, finalmente es hora de proponer los cambios en el comportamiento de carga de archivos de configuración desde Springboot 2.4.

Considere el siguiente escenario: si quiero especificar un perfil específico al ejecutar una prueba Springboot, puedo agregar @ActiveProfile("Test") en la clase de prueba. Si configuro un ApplicationEnvironmentPreparedEvent en algún oyente personalizado en mi aplicación, configurará el perfil según el entorno actual, por ejemplo, env.addActiveProfile("Dev").

Actualmente hay dos perfiles activos. Antes de llamar a application#run, springboot-test usa DefaultActiveProfilesResolver para agregar el perfil definido por la anotación @ActiveProfile al perfil activo (Prueba).

Antes de usar application#run, DefaultActiveProfilesResolver primero agregará el perfil definido por la anotación @ActiveProfile (Prueba) al perfil activo, y luego env.addActiveProfile("Dev") agregará "Dev" como una actividad cuando la prueba esté ejecutando el perfil. , entonces el perfil actualmente activo será ["Test", "Dev"].

Según la introducción anterior, la configuración correspondiente al archivo de configuración (Dev) al final sobrescribirá el archivo de configuración (Prueba) al principio. En las versiones de Springboot anteriores a la 2.4.0, el perfil correspondiente al perfil definido en la clase de prueba @ActiveProfile tenía la máxima prioridad, ajustándonos así esta configuración.

Como se mencionó anteriormente, en Springboot 2.4.0, el listado para manejar archivos de configuración es ConfigFileApplicationListener, así que

echemos un vistazo al código ConfigFileApplicationListener relevante.

En el perfil de inicialización (initializeProfiles), podemos ver que el orden de los archivos de configuración se ha ajustado en este momento, se agrega activadoViaProperty (Prueba) al final, por lo que el orden de los archivos de configuración se convierte en [Desarrollador, Prueba].

En perfiles.poll(), el orden de los archivos de configuración se invierte a [Dev, Test], mientras que en load(), el valor en application-Test.yaml finalmente entra en vigor porque la configuración de prueba archivo La fecha ha caducado.

Pero después de Springboot 2.4.0, ConfigFileApplicationListener ha quedado obsoleto y reemplazado por EnvironmentPostProcessorApplicationListener. EnvironmentPostProcessorApplicationListener completa la carga de la configuración llamando a ConfigDataEnvironmentPostProcessor.

EnvironmentPostProcessorApplicationListener.java

ConfigDataEnvironmentPostProcessor.java

ConfigDataEnvironmentPostProcessor.java

ConfigDataEnvironmentPostProcessor simplemente establece honestamente el perfil activo, sin intercambiar el orden de archivos de configuración. Eventualmente llama a la clase de cargador de recursos definida en spring.factors para cargar el archivo de configuración.

YamlPropertySourceLoader.java

Por cierto, Springboot nos proporciona un buen código para analizar archivos yaml, por lo que cuando necesite analizar archivos yaml, es posible que desee consultar directamente YamlPropertySourceLoader de Springboot.

De esta manera, una vez que la aplicación se actualice a Springboot 2.4.0, se llamará al mismo código de prueba.

A partir de 4.0, el mismo código de prueba utilizará los valores configurados en application-Dev.yaml, lo que provocará que los resultados de la prueba cambien.

Para resolver este problema, de acuerdo con la prioridad del archivo de configuración anterior, puede establecer propiedades en @SpringbootTest para anular el archivo de configuración actual como configuración final.

No es fácil entender un marco. Un pequeño cambio puede hacer que el comportamiento de la aplicación cambie. La única forma es llegar al fondo y resumir constantemente la metodología inmutable utilizada por el marco. personas para resolver todos los problemas.