Dynamically switching between properties files based on request header parameter in spring boot application
You can't switch profiles at runtime. Your options are limited to either creating a new ApplicationContext
which comes with its own drawbacks or you can load the tenant property files at startup and implement a tenant-specific getProperty
method to call when needed.
This ought-to handle the latter case:
@Component
public class TenantProperties {
private Map<String, ConfigurableEnvironment> customEnvs;
@Inject
public TenantProperties(@Autowired ConfigurableEnvironment defaultEnv,
@Value("${my.tenant.names}") List<String> tenantNames) {
this.customEnvs = tenantNames
.stream()
.collect(Collectors.toMap(
Function.identity(),
tenantId -> {
ConfigurableEnvironment customEnv = new StandardEnvironment();
customEnv.merge(defaultEnv);
Resource resource = new ClassPathResource(tenantId + ".properties");
try {
Properties props = PropertiesLoaderUtils.loadProperties(resource);
customEnv.getPropertySources()
.addLast(new PropertiesPropertySource(tenantId, props));
return customEnv;
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}));
}
public String getProperty(String tenantId, String propertyName) {
ConfigurableEnvironment ce = this.customEnvs.get(tenantId);
if (ce == null) {
throw new IllegalArgumentException("Invalid tenant");
}
return ce.getProperty(propertyName);
}
}
You need to add a my.tenant.names
property to your main application properties that contains a comma separated list of tenant names (name1, name2
, etc.). tenant-specific properties are loaded from name1.properties
, ... from the classpath. You get the idea.