Netflix Archaius properties in a Spring project
Archaius Basics
Netflix Archaius is a library for managing configuration for an application. Consider a properties file “sample.properties” holding a property called “myprop”:
myprop=myprop_value_default
This is how the file is loaded up using Archaius:
ConfigurationManager .loadCascadedPropertiesFromResources("sample"); String myProp = DynamicPropertyFactory.getInstance().getStringProperty("myprop", "NOT FOUND").get(); assertThat(myProp, equalTo("myprop_value_default"));
Archaius can load property appropriate to an environment, consider that there is a “sample-perf.properties” with the same configuration over-ridden for perf environment:
myprop=myprop_value_perf
Now Archaius can be instructed to load the configuration in a cascaded way by adding the following in sample.properties file:
myprop=myprop_value_default @next=sample-${@environment}.properties
And the test would look like this:
ConfigurationManager.getDeploymentContext().setDeploymentEnvironment("perf"); ConfigurationManager .loadCascadedPropertiesFromResources("sample"); String myProp = DynamicPropertyFactory.getInstance().getStringProperty("myprop", "NOT FOUND").get(); assertThat(myProp, equalTo("myprop_value_perf"));
Spring Property basics
Spring property basics are very well explained at the Spring Framework reference site here. In short, if there is a property file “sample.properties”, it can be loaded up and referenced the following way:
@Configuration @PropertySource("classpath:/sample.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("myprop")); return testBean; } }
Or even simpler, they can be de-referenced with placeholders this way:
@Configuration @PropertySource("classpath:/sample.properties") public class AppConfig { @Value("${myprop}") private String myProp; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(myProp)); return testBean; } @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } }
Making Archaius properties visible to Spring
So now the question is how to get the Archaius properties visible in Spring, the approach I have taken is a little quick and dirty one but can be cleaned up to suite your needs. My approach is to define a Spring PropertySource which internally delegates to Archaius:
import com.netflix.config.ConfigurationManager; import com.netflix.config.DynamicPropertyFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.PropertySource; import java.io.IOException; public class SpringArchaiusPropertySource extends PropertySource<Void> { private static final Logger LOGGER = LoggerFactory.getLogger(SpringArchaiusPropertySource.class); public SpringArchaiusPropertySource(String name) { super(name); try { ConfigurationManager .loadCascadedPropertiesFromResources(name); } catch (IOException e) { LOGGER.warn( "Cannot find the properties specified : {}", name); } } @Override public Object getProperty(String name) { return DynamicPropertyFactory.getInstance().getStringProperty(name, null).get(); } }
The tricky part is registering this new PropertySource with Spring, this can be done using an ApplicationContextInitializer which is triggered before the application context is initialized:
import com.netflix.config.ConfigurationBasedDeploymentContext; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.util.StringUtils; public class SpringProfileSettingApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { @Override public void initialize(ConfigurableApplicationContext ctx) { ctx.getEnvironment() .getPropertySources() .addFirst(new SpringArchaiusPropertySource("samples")); } }
And finally registering this new ApplicationContextInitializer with Spring is described here. This is essentially it, now the Netflix Archaius properties should work in a Spring application.
Reference: | Netflix Archaius properties in a Spring project from our JCG partner Biju Kunjummen at the all and sundry blog. |
What is samples here? All of the above place you have passed sample but here it is samples. Is it file name?
.addFirst(new SpringArchaiusPropertySource(“samples”));
Second Point is we have made Archaius properties visible to Spring in above code, but that will not hot reload, because context initialization will be done at startup of application. How will be reload it on change in file.