Preface
In order to configure flexibly in projects, we often use configuration files. Common configuration files are such as xml and properties. Springboot allows the use of properties and yaml files as external configurations. The compiler's support for the yaml language is not good enough now, and the properties file is still used as an external configuration.
Before Spring cloud config came out, I implemented the ZK-based configuration center and eliminated the local properties configuration file. The principle is very simple, but I just overloaded mergeProperties() of PropertyPlaceholderConfigurer:
/** * Overload the merge property implementation* First load file properties, then merge into the properties read by the ZK configuration center * * @return Merged property collection* @throws IOException Exception*/@Overrideprotected Properties mergeProperties() throws IOException { Properties result = new Properties(); // Load the configuration of the parent class Properties mergeProperties = super.mergeProperties(); result.putAll(mergeProperties); // Load the configuration read from zk Map<String, String> configs = loadZkConfigs(); result.putAll(configs); return result;} This implementation is quite easy to use in spring projects, but recently some spring-boot projects found that this placeholder implementation and spring boot's @ConfigurationProperties(prefix = "xxx") cannot work well.
That is, the properties are not resolved, and you can read them in the @Value way, but if there are many properties for @Value, it is still quite cumbersome. I still tend to use the prefix of @ConfigurationProperties. So I looked at the spring boot documentation and found that PropertySource
order:
* Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
* @TestPropertySource annotations on your tests.
* @SpringBootTest#properties annotation attribute on your tests.
* Command line arguments.
* Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
* ServletConfig init parameters.
* ServletContext init parameters.
* JNDI attributes from java:comp/env.
* Java System properties (System.getProperties()).
* OS environment variables.
* A RandomValuePropertySource that only has properties in random.*.
* Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
* Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
* Application properties outside of your packaged jar (application.properties and YAML variants).
* Application properties packaged inside your jar (application.properties and YAML variants).
* @PropertySource annotations on your @Configuration classes.
* Default properties (specified using SpringApplication.setDefaultProperties).
It is not difficult to find that it can check the properties in Java system properties. That is to say, just write the properties read by mergeProperties into Java system props, look at the source code, and find a point of entry.
/** * Overload processing property implementation* According to the options, decide whether to write the merged props to the system properties. Spring boot requires * * @param beanFactoryToProcess * @param props Merged properties* @throws BeansException */@Overrideprotected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { // Original logic super.processProperties(beanFactoryToProcess, props); // Write to system property if (writePropsToSystem) { // write all properties to system for spring boot Enumeration<?> propertyNames = props.propertyNames(); while (propertyNames.hasMoreElements()) { String propertyName = (String) propertyNames.nextElement(); String propertyValue = props.getProperty(propertyName); System.setProperty(propertyName, propertyValue); } }} To avoid excessive impact, a switch is set to write system properties. If it is a spring boot project, turn it on, so as to minimize the impact on online non-spring boot projects. Then, @ConfigurationProperties of spring boot perfectly read the properties;
See the specific code: org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor
@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { ConfigurationProperties annotation = AnnotationUtils .findAnnotation(bean.getClass(), ConfigurationProperties.class); if (annotation != null) { postProcessBeforeInitialization(bean, beanName, annotation); } annotation = this.beans.findFactoryAnnotation(beanName, ConfigurationProperties.class); if (annotation != null) { postProcessBeforeInitialization(bean, beanName, annotation); } return bean;}Summarize
The above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.