Common ways for Spring Boot to read configuration files

1, Introduction

  in the actual development process, we often need to obtain the value of the configuration file to realize the configurability of our program. Today, let's take a look at several ways to obtain the value of the configuration file in Spring Boot.

2, Dependency and configuration

2.1 maven dependency

  the version of Spring Boot in this article is the latest version (the latest version is 2.5.2)
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.2</version>
        <relativePath/>
    </parent>
    
    <groupId>com.alian</groupId>
    <artifactId>properties</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>properties</name>
    <description>Spring Boot Read the value of the configuration file</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${parent.version}</version>
        </dependency>

        <!--@PropertySource Use to-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <version>${parent.version}</version>
            <optional>true</optional>
        </dependency>

		<!--This project may not be referenced-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${parent.version}</version>
        </dependency>

		<!--@Data Or log used to-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.14</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

  you can choose according to your project needs.

2.2,application.properties configuration

application.properties

#If referenced
#<dependency>
#    <groupId>org.springframework.boot</groupId>
#    <artifactId>spring-boot-starter-web</artifactId>
#    <version>${parent.version}</version>
#</dependency>
#Then configure the item name and port
server.port=8897
server.servlet.context-path=/properties

  because I built a web project locally

3, Practice (all the following examples are tested by @ PostConstruct)

3.1 get @ Value

The syntax is as follows:

@Value(${Configuration item key:Default value})
private String configValue;

Note: @ value is org springframework. beans. factory. annotation. Value

We are in the configuration file application The following configuration is added in properties to test the @ Value method to obtain the Value of the configuration file

#Define variable test for @ Value
#Request address
value.request.url=https://openapi.alipay.com/gateway.do
#Request application id
value.request.app.id=2019052960295228
#Request signature key
value.request.sign.key=FFFFEA911121494981C5FEBA599C3A99
#Please encrypt the key
value.request.encrypted.key=EEEE9CA14DE545768A0BD9F1435EE507

@Value test source program
ValueService.java

package com.alian.properties.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class ValueService {

    /**
     * Request address
     */
    @Value("${value.request.url}")
    private String url;

    /**
     * Request application id
     */
    @Value("${value.request.app.id}")
    private String appId;

    /**
     * Request signature key
     */
    @Value("${value.request.sign.key}")
    private String signKey;

    /**
     * Request encryption key
     */
    @Value("${value.request.encrypted.key}")
    private String encryptedKey;

    /**
     * Timeout (the default value is set. When the configuration value is not obtained, it is separated by colon and written after colon)
     */
    @Value("${value.request.timeout:20}")
    private int timeOut;

    @PostConstruct
    public void testValue() {
        System.out.println("-------------------@Value Test start-------------------");
        System.out.println("@Value Test acquired request address:" + url);
        System.out.println("@Value Test acquired request application id: " + appId);
        System.out.println("@Value Test acquired request signature key: " + signKey);
        System.out.println("@Value Test acquired request encryption key: " + encryptedKey);
        //If the value of the key is not set in the configuration file, the default value is used
        System.out.println("@Value Default value settings for test acquisition:" + timeOut);
        System.out.println("-------------------@Value End of test-------------------");
    }
}

Operation results:

-------------------@Value Test start-------------------
@Value Test acquired request address: https://openapi.alipay.com/gateway.do
@Value Test acquired request application id: 2019052960295228
@Value Test acquired request signature key: FFFFEA911121494981C5FEBA599C3A99
@Value Test acquired request encryption key: EEEE9CA14DE545768A0BD9F1435EE507
@Value Default value setting for test acquisition: 20
-------------------@Value End of test-------------------

be careful:

  • Use @ Value to obtain the Value of the configuration file. If the key of the configuration item does not exist and the default Value is not set, the program will directly report an error
  • How to set the default Value using @ Value: add a colon after the key of the configuration item, and then write the default Value, such as ${key of the configuration item: default Value}
  • Using @ Value is inconvenient to maintain and manage when there are too many configuration items in the configuration file and too many places are used

3.2. Environment object acquisition

It's easy to use. You can directly use the annotation @ Autowired of spring to import it

    @Autowired
    private Environment environment;

Note: environment is org springframework. core. env. Environment

We continue in the configuration file application The following configuration is added in properties to test the Environment method to obtain the value of the configuration file

#Define variable tests for Environment
#System group
envir.system.group=Alian
#System group
envir.system.level=1
#System name
envir.system.name=administrator
#System password
envir.system.password=e6fa5927cc37437ac6cbe5e988288f80

Environment test source program

EnvironmentService.java

package com.alian.properties.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class EnvironmentService {

    @Autowired
    private Environment environment;

    @PostConstruct
    public void testEnvironment() {
        System.out.println("-------------------Environment Test start-------------------");
        System.out.println("Environment System group obtained by test:" + environment.getProperty("envir.system.group"));
        System.out.println("Environment System level obtained by test:" + environment.getProperty("envir.system.level"));
        System.out.println("Environment System name obtained by test:" + environment.getProperty("envir.system.name"));
        System.out.println("Environment System password obtained by test:" + environment.getProperty("envir.system.password"));
        //If the value of the key is not set in the configuration file, the default value is used
        System.out.println("Environment Default value settings for test acquisition:" + environment.getProperty("envir.system.init", "Initialization parameters are not set"));
        System.out.println("-------------------Environment End of test-------------------");
    }
}

Operation results:

-------------------Environment Test start-------------------
Environment System group obtained by test: Alian
Environment System level obtained by test: 1
Environment System name obtained by test: administrator
Environment System password obtained by test: e6fa5927cc37437ac6cbe5e988288f80
Environment Default value setting for test acquisition: initialization parameter is not set
-------------------Environment End of test-------------------

be careful:

  • Using the Environment object to obtain the value of the configuration file, it is best to use the method with default value: getProperty("configuration item key", "default value") to avoid null value
  • Using the Environment object, you can also get some system startup information. Of course, if there are too many configuration items, there will be problems in maintenance and management

3.3. Get by @ ConfigurationProperties (highly recommended)

   in order to better fit the object-oriented of java, we map the attributes of the configuration file in the way of automatic configuration. After configuration, it can be used directly as a java object. We continue in the configuration file application The following configuration is added in properties to test the @ ConfigurationProperties method to obtain the value of the configuration file

##Define variable tests for Properties
#author
app.author-name=Alian
#Blog website
app.web-url=https://blog.csdn.net/Alian_1223
#Applet application id
app.micro-applet.app-id=wx4etd7e3803c6c555
#Applet application secretId
app.micro-applet.secret-id=e6fa5627cc57437ac8cbe5e988288f80
#Applet timeout
app.micro-applet.expire-time=3600

There's not much nonsense. Just create a new configuration class appproperties java
AppProperties.java

package com.alian.properties.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(value = "app")
public class AppProperties {

    /**
     * Author name
     */
    private String authorName = "";

    /**
     * Blog website
     */
    private String webUrl = "https://blog.csdn.net/Alian_1223";

    /**
     * Applet configuration
     */
    private MicroApplet microApplet;

    @Data
    public static class MicroApplet {
        /**
         * Application id
         */
        private String appId = "";
        /**
         * secretId
         */
        private String secretId = "";
        /**
         * Expiration time
         */
        private int expireTime = 30;
    }
}

be careful:

  • @The prefix of the properties in the configuration file represented by ConfigurationProperties(value = "app") starts with app
  • Remember to add @ Data and @ Component annotations on the configuration class (or add @ EnableConfigurationProperties(value = AppProperties.class) on the startup class)
  • If there are internal class objects, remember to add @ Data, otherwise the Data cannot be mapped
  • According to the mapping rules of. properties type files, the first letter after the dash (-) will be capitalized. At the same time, pay attention to the writing method when there are internal classes

The usage method is also very simple. You can directly use the annotation @ Autowired of spring to introduce it

    @Autowired
    private AppProperties appProperties;

AppProperties test source
PropertiesService.java

package com.alian.properties.service;

import com.alian.properties.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class PropertiesService {

    @Autowired
    private AppProperties appProperties;

    @PostConstruct
    public void testProperties() {
        System.out.println("-------------------Properties Test start-------------------");
        System.out.println("Properties Author of test acquisition:" + appProperties.getAuthorName());
        System.out.println("Properties Blog address obtained by test:" + appProperties.getWebUrl());
        System.out.println("Properties Test acquired applet applications id: " + appProperties.getMicroApplet().getAppId());
        System.out.println("Properties Test acquired applet SecretId: " + appProperties.getMicroApplet().getSecretId());
        System.out.println("Properties Applet timeout for test acquisition:" + appProperties.getMicroApplet().getExpireTime());
        System.out.println("-------------------Properties End of test-------------------");
    }
}

Operation results:

-------------------Properties Test start-------------------
Properties Author of test acquisition: Alian
Properties Blog address obtained by test: https://blog.csdn.net/Alian_1223
Properties Test acquired applet applications id: wx4etd7e3803c6c555
Properties Test acquired applet SecretId: e6fa5627cc57437ac8cbe5e988288f80
Properties Applet timeout for test acquisition: 3600
-------------------Properties End of test-------------------

be careful:

  • There are few type conversions, and the configuration class can directly define general types
  • It is convenient to configure and classify, maintain in one place, and write everywhere without a key
  • More in line with object-oriented writing

3.4. Get by @ PropertySource

   sometimes we have some special configurations, which are stored in a separate configuration file, such as database configuration connection parameters. Similarly, we are in application Create a new configuration file alian.com in the properties peer directory Properties, as follows:
alian.properties

#Blog users
csdn.user-name=Alian
#Blog password
csdn.password=123456
#Blog address
csdn.blog-url=https://blog.csdn.net/Alian_1223
#Blog description
csdn.blog-desp=Come on, let's talk about dry goods!!!

Create a new configuration class alianproperties Java to complete the mapping
ALianProperties.java

package com.alian.properties.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "csdn")
@PropertySource(value = "classpath:alian.properties", encoding = "UTF-8", ignoreResourceNotFound = true) 
public class ALianProperties {

    private String userName;

    private String password;

    private String blogUrl;

    private String blogDesp;
}

be careful:

  • @ConfigurationProperties(value = "csdn") means that the prefix of the properties in the configuration file starts with csdn
  • @In PropertySource, the value property indicates the path of the specified configuration file, and the encoding property indicates the encoding when reading the configuration file. Remember to match the file alias The encoding of properties is consistent. When the value of ignoreResourceNotFound property is true, no error will be reported when the specified configuration file is not found
  • Remember to add @ Component annotation on the configuration class

The usage method is also very simple. You can directly use the annotation @ Autowired of spring to introduce it

	@Autowired
    private ALianProperties ALianProperties;

@PlaceSource test source
PlaceSourceService .java

package com.alian.properties.service;

import com.alian.properties.config.ALianProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;

@Service
public class PlaceSourceService {

    @Autowired
    private ALianProperties ALianProperties;

    @PostConstruct
    public void testPlaceSource() {
        System.out.println("-------------------PlaceSource Test start-------------------");
        System.out.println("Properties Database address obtained by test:" + ALianProperties.getBlogUrl());
        System.out.println("Properties Database user name obtained by test:" + ALianProperties.getUserName());
        System.out.println("Properties Database password obtained by test:" + ALianProperties.getPassword());
        System.out.println("Properties Database connection parameters obtained by test:" + ALianProperties.getBlogDesp());
        System.out.println("-------------------PlaceSource End of test-------------------");
    }
}

Operation results:

-------------------PlaceSource Test start-------------------
Properties Database address obtained by test: https://blog.csdn.net/Alian_1223
Properties Database user name obtained by test: Alian
Properties Database password obtained by test: 123456
Properties Test the database connection parameters obtained: come on, talk about dry goods together!!!
-------------------PlaceSource End of test-------------------

3.5. Native acquisition

We all know the native method, but we don't introduce it more. Go directly to the code
LoadPropertiesService.java

package com.alian.properties.service;

import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import java.util.Properties;

@Service
public class LoadPropertiesService {

    @PostConstruct
    public void testLoadProperties() {
        System.out.println("-------------------LoadProperties Test start-------------------");
        Properties props = new Properties();
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream("load.properties")), StandardCharsets.UTF_8);
            props.load(inputStreamReader);
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        System.out.println("LoadProperties Function name obtained by test:" + props.getProperty("function.name"));
        System.out.println("LoadProperties Function description obtained by test:" + props.getProperty("function.desp"));
        System.out.println("-------------------LoadProperties Test start-------------------");
    }
}

Operation results:

-------------------LoadProperties Test start-------------------
LoadProperties Function name obtained by test: loadProperties
LoadProperties Function description of test acquisition: obtain the value of the native configuration file
-------------------LoadProperties Test start-------------------

be careful:

  • When reading the stream, specify the code to ensure that it is consistent with the file code, otherwise it will cause garbled code

epilogue

   this article mainly introduces several ways to read configuration files. In practical work, the first three methods are used more. Of course, in the future, with the spring cloud configuration center, the method I recommend combined with @ RefreshScope can be used to complete the dynamic refresh of configuration files.

Keywords: Java Spring Spring Boot

Added by Jon12345 on Sat, 15 Jan 2022 23:44:28 +0200