Skip to content

Provide a way to share default properties between applications #27544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
quaff opened this issue Aug 2, 2021 · 2 comments
Closed

Provide a way to share default properties between applications #27544

quaff opened this issue Aug 2, 2021 · 2 comments
Labels
status: duplicate A duplicate of another issue

Comments

@quaff
Copy link
Contributor

quaff commented Aug 2, 2021

Assume there are two applications "foo" and "bar", both have dependency "core", I want extract the common properties for better maintainability.
current:

--- #application.yml from foo
spring.application.name: foo
spring.datasource.url: jdbc:mysql://${mysql.host}:${mysql.port}/${spring.application.name}
mysql:
  host: localhost
  port: 3306

--- #application.yml from bar
spring.application.name: bar
spring.datasource.url: jdbc:mysql://${mysql.host}:${mysql.port}/${spring.application.name}
mysql:
  host: localhost
  port: 3306

expected:

--- #default.yml from core
spring.application.name: bar
spring.datasource.url: jdbc:mysql://${mysql.host}:${mysql.port}/${spring.application.name}
mysql:
  host: localhost
  port: 3306

--- #application.yml from foo
spring.application.name: foo

--- #application.yml from bar
spring.application.name: bar

above default.yml should override spring boot (including devtools) defaults and could be overridden by application.yaml

My solution:

public class DefaultPropertiesPostProcessor implements EnvironmentPostProcessor, Ordered {

	private static final String FILE_NAME = "default.yml";

	public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 11; // after ConfigDataEnvironmentPostProcessor

	@Override
	public int getOrder() {
		return ORDER;
	}

	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
		try {
			List<PropertySource<?>> list = new YamlPropertySourceLoader()
					.load(FILE_NAME, new ClassPathResource(FILE_NAME)).stream().filter(ps -> {
						String onProfile = (String) ps.getProperty("spring.config.activate.on-profile");
						return onProfile == null || environment.acceptsProfiles(Profiles.of(onProfile));
					}).collect(Collectors.toList());
			Collections.reverse(list);
			list.forEach(environment.getPropertySources()::addLast);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

}

I'm not sure it's the best practice, I wish spring boot will provide equivalent.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Aug 2, 2021
@quaff
Copy link
Contributor Author

quaff commented Aug 5, 2021

It's a little similar to DefaultPropertiesPropertySource

/**
* Set default environment properties which will be used in addition to those in the
* existing {@link Environment}.
* @param defaultProperties the additional properties to set
*/
public void setDefaultProperties(Map<String, Object> defaultProperties) {
this.defaultProperties = defaultProperties;
}
/**
* Convenient alternative to {@link #setDefaultProperties(Map)}.
* @param defaultProperties some {@link Properties}
*/
public void setDefaultProperties(Properties defaultProperties) {
this.defaultProperties = new HashMap<>();
for (Object key : Collections.list(defaultProperties.propertyNames())) {
this.defaultProperties.put((String) key, defaultProperties.get(key));
}
}

but has some major differences:

  1. It auto configured by applications, SpringApplication.setDefaultProperties() need be called in each application main method.
  2. It provide the same experience as ConfigDataEnvironmentPostProcessor, properties can be externalized to yaml, and multiple document supported base on spring.config.activate.on-profile.
  3. It should added right after ConfigDataEnvironmentPostProcessor and before any others default sources provide by libraries such as DevToolsPropertyDefaultsPostProcessor and DevToolsHomePropertiesPostProcessor, DefaultPropertiesPropertySource cannot override devtools properties.

Would you take a look at this ? @philwebb

@wilkinsona
Copy link
Member

This looks to be a duplicate of #24688.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: duplicate A duplicate of another issue
Projects
None yet
Development

No branches or pull requests

3 participants