Spring Boot — Override default properties
Spring boot is a very opinionated framework & there are too many libraries working on the similar model which is based on opinions.
The library - spring doc for example is a very famous library responsible to generate and expose the api specifications and swagger ui.
Example Scenario - conditionally disable the exposure of the api specification & swagger UI.
The details of the scenario are:-
- in the production and pre prod environments the spring doc functionality should not expose the swagger specs & UI.
- it relies on a property which is -
springdoc.api-docs.enabled
it’s value istrue
by default. - for environment profiles other than local, dev, uat, etc. the property should be set to
false
even if developer(s) set it true accidently.
Solution
For conditionally overriding a property we can use the Application listener and configure that in the spring.factories
file
- Create a file as below:-
package in.neuw.artifact.listeners;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.util.CollectionUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;
public class ApplicationEnvironmentPreparedEventListener implements ApplicationListener<ApplicationEnvironmentPreparedEvent> {
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
System.out.println(Arrays.stream(environment.getActiveProfiles()).toList());
// this is true by default
System.out.println("existing value of springdoc.api-docs.enabled --> " + environment.getProperty("springdoc.api-docs.enabled"));
// check if activeProfiles is not empty.
if (!CollectionUtils.isEmpty(List.of(environment.getActiveProfiles()))) {
// check if active profiles contains either prod or pre-prod.
// better to club this condition with previous one, but for easier understanding have nested it.
if(List.of(environment.getActiveProfiles()).stream().anyMatch(v -> Set.of("prod", "pre-prod").contains(v))) {
Properties props = new Properties();
// override the value to false for prod/ pre-prod instances
props.put("springdoc.api-docs.enabled", "false");
environment.getPropertySources().addFirst(new PropertiesPropertySource("opinion-override-props", props));
}
}
}
}
2. Create a file spring.factories
at a location src/main/resources/META-INF
3. Content of the spring.factories
should be as below(change the package location as per your code/ project setup):-
org.springframework.context.ApplicationListener=in.neuw.artifact.listeners.ApplicationEnvironmentPreparedEventListener
Test & Run
Default Scenario - Run the project in default configuration, the swagger specification and config urls will work just fine.
Required Scenario - Run the project with prod as active profile, the swagger specification and config urls will not load at all, you will get 404.
You can reach me over LinkedIn for any questions and queries:-