This is the 16th day of my participation in Gwen Challenge


Introduction to the

EnvironmentPostProcessor is a post-processor provided by Spring Boot that handles ConfigurableEnvironment objects for Spring applications, such as adding default values.

define

EnvironmentPostProcessor is a functional interface defined as follows:

package org.springframework.boot.env;

@FunctionalInterface
public interface EnvironmentPostProcessor {

    /**
     * Post-process the given {@code environment}.
     * @param environment the environment to post-process
     * @param application the application to which the environment belongs
     */
    void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);

}
Copy the code

usage

This article uses changing the default service port of a Spring Boot application as an example to show how to use EnvironmentPostProcessor to change the environment variable of Spring Boot.

By default, the default service port for Spring Boot applications is 8080. This can also be changed through server.port, but this change only applies to the current project. How do you change the default service goods for all projects under a company or organization?

First, customize a class that implements EnvironmentPostProcessor, such as modifying the default port,

public class ServerEnvironmentPostProcessor implements EnvironmentPostProcessor { public static final String SERVER_PORT_PROPERTY_NAME = "server.port"; @Override public void postProcessEnvironment(final ConfigurableEnvironment environment, final SpringApplication application) { environment.getPropertySources() .addLast(new MapPropertySource("defaultServerProperties", Collections.singletonMap(SERVER_PORT_PROPERTY_NAME, 80))); }}Copy the code

This code is equivalent to declaring the following configuration in the application configuration file:

server.port=80
Copy the code

Then add the following configuration to the classpath:/ meta-INF/spring.Factories file:

# EnvironmentPostProcessor
org.springframework.boot.env.EnvironmentPostProcessor=\
org.ifinalframework.boot.env.ServerEnvironmentPostProcessor
Copy the code

Start the Spring application and the service will run on port 80.

The above implementation is valid only if the specified server.port is not displayed. This is because addLast() is used. If you want to ignore the specified configuration, use addFirst() injection.

Principle (How)

From Spring Boot 2.4.0, listener EnvironmentPostProcessorApplicationListener application is introduced.

This interface implements the SmartApplicationListener and overwrites the supportsEventType(Class) method to support ApplicationEvent of the following types:

  • ApplicationEnvironmentPreparedEvent
  • ApplicationPreparedEvent
  • ApplicationFailedEvent
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
    return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
            || ApplicationPreparedEvent.class.isAssignableFrom(eventType)
            || ApplicationFailedEvent.class.isAssignableFrom(eventType);
}
Copy the code

So when ready SpringApplication Envirmonent and publish ApplicationEnvironmentPreparedEvent events, will callback its onApplicationEvent (ApplicationEvent) method, Triggering onApplicationEnvironmentPreparedEvent () method:

@Override
public void onApplicationEvent(ApplicationEvent event) {
    if (event instanceof ApplicationEnvironmentPreparedEvent) {
        onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
    }
    if (event instanceof ApplicationPreparedEvent) {
        onApplicationPreparedEvent();
    }
    if (event instanceofApplicationFailedEvent) { onApplicationFailedEvent(); }}Copy the code

In onApplicationEnvironmentPreparedEvent () method, By calling the SpringFactoriesLoader. LoadFactoryNames (EnvironmentPostProcessor. Class, ClassLoader) loads the EnvironmentPostProcessor instance declared in the/meta-INF /spring.factories file.

summary

This paper takes server. Port as an example to briefly describe the basic use and implementation principle of the Spring environment postprocessor. Developers can use this extension to process or customize the Spring default environment and improve the efficiency of program development to a greater extent.