The book "Java in the cloud. Spring Boot, Spring Cloud, Cloud Foundry »
Hello! Basically, this book is intended for Java and JVM machine developers who are looking for ways to create better software in a short time using Spring Boot, Spring Cloud and Cloud Foundry. It is for those who have already heard the noise that has risen around microservices. You may have already realized how stratospheric heights the Spring Boot environment has flown, and you are surprised that businesses today use the Cloud Foundry platform. If so, then this book is for you.
This chapter will look at how to implement an application’s configuration.
Define a number of vocabulary terms. When it comes to configuration in Spring, most often it is about inputting to the Spring environment various implementations of the application context - ApplicationContext , which helps the container to understand how to connect beans. Such a configuration can be represented as an XML file, which must be submitted to ClassPathXmlApplicationContext , or Java classes annotated in a manner that can be provided to the AnnotationConfigApplicationContext object . And of course, when studying the latter option, we will refer to the Java configuration.
But in this chapter we are going to look at the configuration as defined in the manifest 12-factor application.. In this case, it refers to literal values that can vary from one environment to another: we are talking about passwords, ports and host names, or property flags. The configuration ignores magic constants embedded in the code. The manifest includes an excellent criterion for correct configuration: can the application code base be an open source at any time without disclosing and compromising important credentials? This type of configuration refers solely to values that vary from one environment to another, and does not apply, for example, to connecting Spring beans or configuring Ruby routes.
In Spring, the configuration style corresponding to 12 factors has been supported since the appearance of the PropertyPlaceholderConfigurer class . Once its instance is determined, it replaces the literals in the XML configuration with the values extracted from the file with the .properties extension. In Spring, PropertyPlaceholderConfigurer has been offered since 2003. Spring 2.5 introduces support for the XML namespace, as well as support for this property lookup space. This allows you to substitute the literal values of the definitions of beans into the XML configurations with the values assigned to the keys in the external properties file (in this case, the simple.properties file, which may appear in the class path or be external to the application).
Configuration in the style of 12 factors is aimed at eliminating the unreliability of the existing magic strings, that is, values like database addresses and accounts for connecting to them, ports, etc., which are hard coded in the compiled application. If the configuration is moved outside the application, then it can be replaced without resorting to this new code assembly.
Let's look at a sample of how to use the PropertyPlaceholderConfigurer class, the XML definitions of Spring beans, and the file with the .properties extension outside the application. We just need to print the value in this property file. This will help to make the code shown in Example 3.1.
Example 3.1. Properties File: some.properties
This is the Spring-owned ClassPathXmlApplicationContext class, so we use the XML namespace from the Spring context and point to our file some.properties. Then we use literals in the form of bean-components in the form of $ {configuration.projectName}, and Spring during the execution will replace them with values from our property file (Example 3.2).
Example 3.2. Spring Configuration XML File
(1) classpath: location referencing the file in the current compiled block of code (.jar, .war, etc.). Spring supports many alternatives, including file: and url:, allowing a file to exist apart from a block of code.
Finally, let's look at how the Java class looks, thanks to which it is possible to bring all this together (Example 3.3).
Example 3.3. A Java class that must be configured with the value of the
package classic property ;
The first example uses the XML format for the configuration of Spring beans. In Spring 3.0 and 3.1, the situation for developers using Java configuration has improved significantly. In these issues, the Value annotation and the Environment abstraction were introduced .
In the course of executing a code, the Environment abstraction is indirectly related to the environment in which it is running and allows the application to ask a question (“What is the line.separator line separator on this platform?”) About the properties of the environment. Abstraction acts as a mapping from keys and values. By configuring the PropertySource PropertySource in Environment, you can configure the location from which these values will be read. By default, Spring loads system keys and environment values, such as line.separator. Spring can be instructed to load configuration keys from a file in the same order that could be used in early releases of the Spring property lookup solution using the @PropertySource annotation.
Abstract Valueprovides a way to embed environment values in constructors, setters, fields, etc. These values can be calculated using the Spring Expression Language or the property substitution syntax, provided the PropertySourcesPlaceholderConfigurer is registered , as done in Example 3.4.
Example 3.4. Register PropertySourcesPlaceholderConfigurer
package env;
(1) The @PropertySource annotation is an abbreviation like property-placeholder that configures a PropertySource from a file with the .properties extension.
(2) PropertySourcesPlaceholderConfigurer must be registered as a static bean component, because it is an implementation of the BeanFactoryPostProcessor and must be called at an early stage of the initialization life cycle in Spring bean components. When using XML configuration of beans in Spring, this nuance is not visible.
(3) You can decorate the fields with the Value annotation (but do not do this, otherwise the code will not pass the test!) ...
(4) ... or with the Value annotation you can decorate the design parameters ...
(5) ... or use the installation methods ...
(6) ... or implement the Spring Environment object and perform key resolution manually.
(7) Parameters with the Value annotation can also be used in the argument provider of Bean methods in the Spring Java configuration.
In this example, the values are loaded from the file simple.properties, and then it contains the value configuration.projectName, provided in various ways.
Among other things, the Environment abstraction introduces profiles . This allows you to assign labels (profiles) in order to group the beans. Profiles should be used to describe bean-components and bean-graphs, varying from medium to medium. Multiple profiles can be activated simultaneously. Bean components that do not have profiles assigned to them are always activated. Beans that have a default profile are activated only if they have no other active profiles. The profile attribute can be specified in a bean definition in XML or in tag classes, configuration classes, individual beans, or in the Provider Bean methods using Profile .
Profiles allow you to describe sets of beans that must be created in one environment a little differently than in another. In the local dev development profile, for example, you can use the built-in H2 data source javax.sql.DataSource, and then, when the prod profile is active, switch to the javax.sql.DataSource data source for PostgreSQL, obtained using JNDI search or by reading properties from the environment variable in Cloud Foundry . In both cases, your code will work: you get javax.sql.DataSource, but the decision on which particular instance to use is made by activating one profile or several (example 3.5).
Example 3.5. Demonstrate that @Configuration classes can load different configuration files and provide different bean components based on the
active profile
(1) This configuration class and all its Bean definitions will be calculated only if the prod profile is active.
(2) This configuration class and all its Bean definitions will be calculated only if the dev profile is active or no profile is active, including dev.
(3) This InitializingBean component simply records the current active profile and enters the value that was eventually entered into the properties file.
(4) Activating a profile (or profiles) programmatically is quite simple.
Spring responds to several other profile activation methods that use the spring_profiles_active or spring.profiles.active token. A profile can be set using an environment variable (for example, SPRING_PROFILES_ACTIVE), JVM properties (‑Dspring.profiles.active = ...), the initialization parameter of a servlet application, or programmatically.
Spring Boot significantly improves the situation. The environment will initially automatically load properties from a hierarchy of previously known locations. Command line arguments override property values obtained from JNDI, which override properties obtained from System.getProperties (), etc.
- Command line arguments.
- JNDI attributes from java: comp / env.
- Properties System.getProperties ().
- Operating system environment variables.
- External properties files in the filesystem: (config /)? Application. (Yml.properties).
- Internal properties files in the archive (config /)? Application. (Yml.properties).
- Annotation @PropertySource in configuration classes.
- Source properties from SpringApplication.getDefaultProperties ().
If a profile is active, data will be automatically read from configuration files based on the profile name, for example, from a file such as src / main / resources / application-foo.properties, where foo is the current profile.
If the SnakeYAML library is mentioned in the classpath, the YAML files will also be automatically loaded, following basically the same convention.
The contents of the file with the extension .yml shown in Example 3.6.
Example 3.6. Property file application.yml. The data is presented in a hierarchical order.
In addition, the Spring Boot environment greatly simplifies obtaining the correct result in general cases. It turns the -D arguments into java process and environment variables available as properties. It even normalizes them, in which the $ CONFIGURATION_PROJECTNAME environment variable (CONFIGURATION_NAME PROJECT) or the -D argument in the form ‑Dconfiguration.projectName (project_name_configuration) are available using the configuration.projectName key (configuration.project_name) in the same way. The spring_profiles_active token is available.
Configuration values are strings and, with a sufficient number of them, they can become unreadable when trying to make sure that such keys do not themselves become magic strings in the code. Spring Boot introduces the component type @ConfigurationProperties. When you annotate a POJO — Plain Old Java Object (a plain old Java object) —– using @ConfigurationProperties and specifying the prefix, Spring will attempt to map all properties that begin with this prefix to POJO properties. In the example below, the value for configuration.projectName will be mapped to a POJO instance, which all code can then embed and dereference for type-safe reading of values. As a result, you will only have a mapping from (String) key in one place (Example 3.7).
Example 3.7. Automatic resolution of properties from src / main / resources / application.yml
package boot;
(1) The @EnableConfigurationProperties annotation instructs Spring to map properties to POJO objects annotated with @ConfigurationProperties.
(2) The @ConfigurationProperties annotation indicates to Spring that this bean should be used as the root component for all properties starting with configuration., Followed by tokens mapped to the properties of the object.
(3) The projectName field will eventually have the value assigned to the configuration.projectName property key.
Spring Boot actively applies the @ConfigurationProperties mechanism to enable users to redefine the elementary components of the system. You may notice that property keys allow you to make changes, for example, by adding the org.springframework.boot: spring-boot-starter-actuator dependency to a Spring Boot based web application and then visiting page 127.0.0.1 : 8080 / configprops.
You will get a list of supported configuration properties based on the types represented in the classpath at run time. As the number of Spring Boot types grows, additional properties will be shown. At this endpoint, the properties exported by your POJO objects annotated with @ConfigurationProperties will also be displayed.
So far so good, but it is necessary that things go even more successfully. We still did not answer the questions about common applications:
The problem of configuration centralization can be solved by saving the configuration in one directory and pointing all applications to it. You can also install version control of this directory using Git or Subversion. Then the support required for verification and registration will be obtained. But the last two requirements will still not be fulfilled, so something more sophisticated is needed. Refer to the Spring Cloud configuration server . The Spring Cloud platform offers a configuration server and client for this server.
The Spring Cloud Config server is a REST API to which our customers will connect to pick up their configuration. The server also manages a version control configuration repository. It is an intermediary between our clients and the configuration repository and thus is in a favorable position, allowing to implement security tools for connections from customers to the service and connections from the service to the configuration storage with version control. The Spring Cloud Config client provides client applications with a new scope, refresh, which enables them to configure Spring components again without restarting the application.
Consider a simple example. First we set up the Spring Cloud Config server. Several Spring Boot applications can access one such service at once. You need somewhere and somehow make it function. Then it will only be necessary to inform all our services about where to find the configuration service. It works as a kind of intermediary for configuration keys and values that it reads from Git storage over the network or from disk. Add org.springframework.cloud: spring-cloud-config-server to your Spring Boot application assembly to enter the Spring Cloud Config server (Example 3.8).
Example 3.8. To embed a configuration server into an assembly, use the @EnableConfigServer annotation
(1) Using the @EnableConfigServer annotation installs Spring Cloud Config server.
Example 3.9 shows the configuration for the configuration service.
Example 3.9. Configuration server configuration src / main / resources / application.yml
server.port = 8888
spring.cloud.config.server.git.uri = \
github.com/cloud-native-java/config-server-configuration-repository (1)
(1) An indication of a working Git repository that has a local character or is accessible over the network (for example, on GitHub (https://github.com/)) and used by the Spring Cloud Config server.
Here, the Spring Cloud configuration service is instructed to search for configuration files for individual clients in the Git storage on GitHub. We pointed to this repository, but a link to any valid Git URI would fit. Of course, he doesn’t even have to do with the Git system, you can use Subversion or even unmanaged directories (although we strongly advise against this). In this case, the repository URI is hard-coded, but there’s nothing to prevent it from getting from the -D argument, the argument — or from the environment variable.
»More information about the book can be found on the publisher's website
» Table of contents
» Fragment
For Habrozhiteley 20% discount on the coupon - Java
Excerpt 3. Configuration style of twelve factor applications
This chapter will look at how to implement an application’s configuration.
Define a number of vocabulary terms. When it comes to configuration in Spring, most often it is about inputting to the Spring environment various implementations of the application context - ApplicationContext , which helps the container to understand how to connect beans. Such a configuration can be represented as an XML file, which must be submitted to ClassPathXmlApplicationContext , or Java classes annotated in a manner that can be provided to the AnnotationConfigApplicationContext object . And of course, when studying the latter option, we will refer to the Java configuration.
But in this chapter we are going to look at the configuration as defined in the manifest 12-factor application.. In this case, it refers to literal values that can vary from one environment to another: we are talking about passwords, ports and host names, or property flags. The configuration ignores magic constants embedded in the code. The manifest includes an excellent criterion for correct configuration: can the application code base be an open source at any time without disclosing and compromising important credentials? This type of configuration refers solely to values that vary from one environment to another, and does not apply, for example, to connecting Spring beans or configuring Ruby routes.
Spring Framework Support
In Spring, the configuration style corresponding to 12 factors has been supported since the appearance of the PropertyPlaceholderConfigurer class . Once its instance is determined, it replaces the literals in the XML configuration with the values extracted from the file with the .properties extension. In Spring, PropertyPlaceholderConfigurer has been offered since 2003. Spring 2.5 introduces support for the XML namespace, as well as support for this property lookup space. This allows you to substitute the literal values of the definitions of beans into the XML configurations with the values assigned to the keys in the external properties file (in this case, the simple.properties file, which may appear in the class path or be external to the application).
Configuration in the style of 12 factors is aimed at eliminating the unreliability of the existing magic strings, that is, values like database addresses and accounts for connecting to them, ports, etc., which are hard coded in the compiled application. If the configuration is moved outside the application, then it can be replaced without resorting to this new code assembly.
PropertyPlaceholderConfigurer class
Let's look at a sample of how to use the PropertyPlaceholderConfigurer class, the XML definitions of Spring beans, and the file with the .properties extension outside the application. We just need to print the value in this property file. This will help to make the code shown in Example 3.1.
Example 3.1. Properties File: some.properties
configuration.projectName=Spring Framework
This is the Spring-owned ClassPathXmlApplicationContext class, so we use the XML namespace from the Spring context and point to our file some.properties. Then we use literals in the form of bean-components in the form of $ {configuration.projectName}, and Spring during the execution will replace them with values from our property file (Example 3.2).
Example 3.2. Spring Configuration XML File
<context:property-placeholder location="classpath:some.properties"/> (1)
<bean class="classic.Application">
<property name="configurationProjectName"
value="${configuration.projectName}"/>
</bean>
(1) classpath: location referencing the file in the current compiled block of code (.jar, .war, etc.). Spring supports many alternatives, including file: and url:, allowing a file to exist apart from a block of code.
Finally, let's look at how the Java class looks, thanks to which it is possible to bring all this together (Example 3.3).
Example 3.3. A Java class that must be configured with the value of the
package classic property ;
import org.apache.commons.logging.LogFactory;import org.springframework.context.support.ClassPathXmlApplicationContext;
publicclassApplication{
publicstaticvoid main(String[] args) {
new ClassPathXmlApplicationContext("classic.xml");
}
publicvoid setConfigurationProjectName(String pn) {
LogFactory.getLog(getClass()).info("the configuration project name is " + pn);
}
}
The first example uses the XML format for the configuration of Spring beans. In Spring 3.0 and 3.1, the situation for developers using Java configuration has improved significantly. In these issues, the Value annotation and the Environment abstraction were introduced .
Abstraction Environment and Value
In the course of executing a code, the Environment abstraction is indirectly related to the environment in which it is running and allows the application to ask a question (“What is the line.separator line separator on this platform?”) About the properties of the environment. Abstraction acts as a mapping from keys and values. By configuring the PropertySource PropertySource in Environment, you can configure the location from which these values will be read. By default, Spring loads system keys and environment values, such as line.separator. Spring can be instructed to load configuration keys from a file in the same order that could be used in early releases of the Spring property lookup solution using the @PropertySource annotation.
Abstract Valueprovides a way to embed environment values in constructors, setters, fields, etc. These values can be calculated using the Spring Expression Language or the property substitution syntax, provided the PropertySourcesPlaceholderConfigurer is registered , as done in Example 3.4.
Example 3.4. Register PropertySourcesPlaceholderConfigurer
package env;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import javax.annotation.PostConstruct;
(1)
@Configuration@PropertySource("some.properties")publicclassApplication{
privatefinal Log log = LogFactory.getLog(getClass());
public static void main(String[] args) throws Throwable {
new AnnotationConfigApplicationContext(Application.class);
}
(2)
@Bean
static PropertySourcesPlaceholderConfigurer pspc() {
return new PropertySourcesPlaceholderConfigurer();
}
(3)
@Value("${configuration.projectName}")private String fieldValue;
(4)
@Autowired
Application(@Value("${configuration.projectName}") String pn) {
log.info("Application constructor: " + pn);
}
(5)
@Value("${configuration.projectName}")
void setProjectName(String projectName) {
log.info("setProjectName: " + projectName);
}
(6)
@Autowired
void setEnvironment(Environment env) {
log.info("setEnvironment: " + env.getProperty("configuration.projectName"));
}
(7)
@Bean
InitializingBean both(Environment env,
@Value("${configuration.projectName}") String projectName) {
return () -> {
log.info("@Bean with both dependencies (projectName): " + projectName);
log.info("@Bean with both dependencies (env): "
+ env.getProperty("configuration.projectName"));
};
}
@PostConstruct
void afterPropertiesSet() throws Throwable {
log.info("fieldValue: " + this.fieldValue);
}
}
(1) The @PropertySource annotation is an abbreviation like property-placeholder that configures a PropertySource from a file with the .properties extension.
(2) PropertySourcesPlaceholderConfigurer must be registered as a static bean component, because it is an implementation of the BeanFactoryPostProcessor and must be called at an early stage of the initialization life cycle in Spring bean components. When using XML configuration of beans in Spring, this nuance is not visible.
(3) You can decorate the fields with the Value annotation (but do not do this, otherwise the code will not pass the test!) ...
(4) ... or with the Value annotation you can decorate the design parameters ...
(5) ... or use the installation methods ...
(6) ... or implement the Spring Environment object and perform key resolution manually.
(7) Parameters with the Value annotation can also be used in the argument provider of Bean methods in the Spring Java configuration.
In this example, the values are loaded from the file simple.properties, and then it contains the value configuration.projectName, provided in various ways.
Profiles
Among other things, the Environment abstraction introduces profiles . This allows you to assign labels (profiles) in order to group the beans. Profiles should be used to describe bean-components and bean-graphs, varying from medium to medium. Multiple profiles can be activated simultaneously. Bean components that do not have profiles assigned to them are always activated. Beans that have a default profile are activated only if they have no other active profiles. The profile attribute can be specified in a bean definition in XML or in tag classes, configuration classes, individual beans, or in the Provider Bean methods using Profile .
Profiles allow you to describe sets of beans that must be created in one environment a little differently than in another. In the local dev development profile, for example, you can use the built-in H2 data source javax.sql.DataSource, and then, when the prod profile is active, switch to the javax.sql.DataSource data source for PostgreSQL, obtained using JNDI search or by reading properties from the environment variable in Cloud Foundry . In both cases, your code will work: you get javax.sql.DataSource, but the decision on which particular instance to use is made by activating one profile or several (example 3.5).
Example 3.5. Demonstrate that @Configuration classes can load different configuration files and provide different bean components based on the
active profile
package profiles;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
@ConfigurationpublicclassApplication{
private Log log = LogFactory.getLog(getClass());
@Bean
static PropertySourcesPlaceholderConfigurer pspc() {
return new PropertySourcesPlaceholderConfigurer();
}
(1)
@Configuration@Profile("prod")@PropertySource("some-prod.properties")public static classProdConfiguration{
@Bean
InitializingBean init() {
return () -> LogFactory.getLog(getClass()).info("prod InitializingBean");
}
}
@Configuration@Profile({ "default", "dev" })
(2)
@PropertySource("some.properties")public static classDefaultConfiguration{
@Bean
InitializingBean init() {
return () -> LogFactory.getLog(getClass()).info("default InitializingBean");
}
}
(3)
@Bean
InitializingBean which(Environment e,
@Value("${configuration.projectName}") String
projectName) {
return () -> {
log.info("activeProfiles: '"
+ StringUtils.arrayToCommaDelimitedString(e.getActiveProfiles()) +
"'");
log.info("configuration.projectName: " + projectName);
};
}
public static void main(String[] args) {
AnnotationConfigApplicationContext ac = new
AnnotationConfigApplicationContext();
ac.getEnvironment().setActiveProfiles("dev"); (4)
ac.register(Application.class);
ac.refresh();
}
}
(1) This configuration class and all its Bean definitions will be calculated only if the prod profile is active.
(2) This configuration class and all its Bean definitions will be calculated only if the dev profile is active or no profile is active, including dev.
(3) This InitializingBean component simply records the current active profile and enters the value that was eventually entered into the properties file.
(4) Activating a profile (or profiles) programmatically is quite simple.
Spring responds to several other profile activation methods that use the spring_profiles_active or spring.profiles.active token. A profile can be set using an environment variable (for example, SPRING_PROFILES_ACTIVE), JVM properties (‑Dspring.profiles.active = ...), the initialization parameter of a servlet application, or programmatically.
Bootiful configuration
Spring Boot significantly improves the situation. The environment will initially automatically load properties from a hierarchy of previously known locations. Command line arguments override property values obtained from JNDI, which override properties obtained from System.getProperties (), etc.
- Command line arguments.
- JNDI attributes from java: comp / env.
- Properties System.getProperties ().
- Operating system environment variables.
- External properties files in the filesystem: (config /)? Application. (Yml.properties).
- Internal properties files in the archive (config /)? Application. (Yml.properties).
- Annotation @PropertySource in configuration classes.
- Source properties from SpringApplication.getDefaultProperties ().
If a profile is active, data will be automatically read from configuration files based on the profile name, for example, from a file such as src / main / resources / application-foo.properties, where foo is the current profile.
If the SnakeYAML library is mentioned in the classpath, the YAML files will also be automatically loaded, following basically the same convention.
The YAML specification page states that "YAML is a human data standard for data serialization for all programming languages." YAML is a hierarchical representation of values. In regular files with the .properties extension, the hierarchy is denoted by a period (“.”), While in YAML files, the newline character and an additional indent level are used. It would be nice to use these files to avoid having to specify common roots in the presence of highly branched configuration trees.
The contents of the file with the extension .yml shown in Example 3.6.
Example 3.6. Property file application.yml. The data is presented in a hierarchical order.
configuration:
projectName : Spring Boot
management:
security:
enabled: false
In addition, the Spring Boot environment greatly simplifies obtaining the correct result in general cases. It turns the -D arguments into java process and environment variables available as properties. It even normalizes them, in which the $ CONFIGURATION_PROJECTNAME environment variable (CONFIGURATION_NAME PROJECT) or the -D argument in the form ‑Dconfiguration.projectName (project_name_configuration) are available using the configuration.projectName key (configuration.project_name) in the same way. The spring_profiles_active token is available.
Configuration values are strings and, with a sufficient number of them, they can become unreadable when trying to make sure that such keys do not themselves become magic strings in the code. Spring Boot introduces the component type @ConfigurationProperties. When you annotate a POJO — Plain Old Java Object (a plain old Java object) —– using @ConfigurationProperties and specifying the prefix, Spring will attempt to map all properties that begin with this prefix to POJO properties. In the example below, the value for configuration.projectName will be mapped to a POJO instance, which all code can then embed and dereference for type-safe reading of values. As a result, you will only have a mapping from (String) key in one place (Example 3.7).
Example 3.7. Automatic resolution of properties from src / main / resources / application.yml
package boot;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
(1)
@EnableConfigurationProperties@SpringBootApplicationpublicclassApplication{
privatefinal Log log = LogFactory.getLog(getClass());
publicstaticvoidmain(String[] args){
SpringApplication.run(Application.class);
}
@AutowiredpublicApplication(ConfigurationProjectProperties cp){
log.info("configurationProjectProperties.projectName = "
+ cp.getProjectName());
}
}
(2)
@Component@ConfigurationProperties("configuration")
classConfigurationProjectProperties{
private String projectName; (3)
public String getProjectName(){
return projectName;
}
publicvoidsetProjectName(String projectName){
this.projectName = projectName;
}
}
(1) The @EnableConfigurationProperties annotation instructs Spring to map properties to POJO objects annotated with @ConfigurationProperties.
(2) The @ConfigurationProperties annotation indicates to Spring that this bean should be used as the root component for all properties starting with configuration., Followed by tokens mapped to the properties of the object.
(3) The projectName field will eventually have the value assigned to the configuration.projectName property key.
Spring Boot actively applies the @ConfigurationProperties mechanism to enable users to redefine the elementary components of the system. You may notice that property keys allow you to make changes, for example, by adding the org.springframework.boot: spring-boot-starter-actuator dependency to a Spring Boot based web application and then visiting page 127.0.0.1 : 8080 / configprops.
The end points of the actuator will be discussed in more detail in Chapter 13. They are locked and require a default username and password. Security measures can be disabled (but only to look at these points) by specifying management.security.enabled = false in the application.properties file (or application.yml).
You will get a list of supported configuration properties based on the types represented in the classpath at run time. As the number of Spring Boot types grows, additional properties will be shown. At this endpoint, the properties exported by your POJO objects annotated with @ConfigurationProperties will also be displayed.
Centralized logged configuration using Spring Cloud Configuration Server
So far so good, but it is necessary that things go even more successfully. We still did not answer the questions about common applications:
- after changes made to the application configuration, a restart will be required;
- no traceability: how to identify changes put into operation and roll back if necessary?
- configuration is decentralized; it is not immediately clear where changes should be made in order to change one or another aspect;
- There is no installation support for encoding and decoding for security.
Spring Cloud Configuration Server
The problem of configuration centralization can be solved by saving the configuration in one directory and pointing all applications to it. You can also install version control of this directory using Git or Subversion. Then the support required for verification and registration will be obtained. But the last two requirements will still not be fulfilled, so something more sophisticated is needed. Refer to the Spring Cloud configuration server . The Spring Cloud platform offers a configuration server and client for this server.
The Spring Cloud Config server is a REST API to which our customers will connect to pick up their configuration. The server also manages a version control configuration repository. It is an intermediary between our clients and the configuration repository and thus is in a favorable position, allowing to implement security tools for connections from customers to the service and connections from the service to the configuration storage with version control. The Spring Cloud Config client provides client applications with a new scope, refresh, which enables them to configure Spring components again without restarting the application.
Technologies similar to the Spring Cloud Config server play an important role, but entail additional business costs. Ideally, this duty should be shifted to the platform and automated. When using Cloud Foundry, you can find the Config Server service in the services directory, which is based on the use of the Spring Cloud Config server.
Consider a simple example. First we set up the Spring Cloud Config server. Several Spring Boot applications can access one such service at once. You need somewhere and somehow make it function. Then it will only be necessary to inform all our services about where to find the configuration service. It works as a kind of intermediary for configuration keys and values that it reads from Git storage over the network or from disk. Add org.springframework.cloud: spring-cloud-config-server to your Spring Boot application assembly to enter the Spring Cloud Config server (Example 3.8).
Example 3.8. To embed a configuration server into an assembly, use the @EnableConfigServer annotation
package demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
(1)
@SpringBootApplication@EnableConfigServerpublicclassApplication{
publicstaticvoidmain(String[] args){
SpringApplication.run(Application.class, args);
}
}
(1) Using the @EnableConfigServer annotation installs Spring Cloud Config server.
Example 3.9 shows the configuration for the configuration service.
Example 3.9. Configuration server configuration src / main / resources / application.yml
server.port = 8888
spring.cloud.config.server.git.uri = \
github.com/cloud-native-java/config-server-configuration-repository (1)
(1) An indication of a working Git repository that has a local character or is accessible over the network (for example, on GitHub (https://github.com/)) and used by the Spring Cloud Config server.
Here, the Spring Cloud configuration service is instructed to search for configuration files for individual clients in the Git storage on GitHub. We pointed to this repository, but a link to any valid Git URI would fit. Of course, he doesn’t even have to do with the Git system, you can use Subversion or even unmanaged directories (although we strongly advise against this). In this case, the repository URI is hard-coded, but there’s nothing to prevent it from getting from the -D argument, the argument — or from the environment variable.
»More information about the book can be found on the publisher's website
» Table of contents
» Fragment
For Habrozhiteley 20% discount on the coupon - Java