Break down the configuration files used in Java projects (properties)

Soul torture: How to make the configuration changes take effect without restarting the service? Are there any tricks?

Soul torture: In Java projects, you can always see traces of files with .properties as suffixes. How are these configuration files loaded?

During the project development process, you will often encounter some parameters that change frequently, such as the connection address, name, user name, and password of the database to be connected; for example, the URL to access the three-party service. Considering the versatility of the program, these parameters cannot often be directly written into the program, and are usually handled gracefully by means of configuration files.

 In the Java project, the properties file belongs to the simpler category, but although it is simple, it is still necessary to talk about how it is used in the project. Try to interpret it through the source code to let you really understand it and bring you a deep experience in Java. The meaning of overloading.

 

1. Despite its simplicity, the format still needs to be looked at.

Compared with the ini configuration file discussed last time, the properties file format does not have the concept of Section, but it is a lot simpler.

 

 

 

 The above picture is a configuration required for a jdbc connection, where each line starting with # is comment information, and each line configuration separated by an equal sign is commonly known as a key-value pair, and the left side of the equal sign is the key (in the code Variable), the value to the right of the equal sign is the value (the value configured according to the actual scenario).

 

2. Despite its simplicity, the Java source code should still be checked.

The java.util.Properties class is provided in Java and is mainly used for reading and writing configuration files.

 

 

One picture grasps the blood relationship. Obviously, Properties inherits from Hashtable. In the final analysis, it is a Map, and the most special place of Properties is that its keys and values ​​are all string types.

 

Understand the outline from the overall situation, and then walk into the JDK source code, follow the ideas, and go deeper step by step.

 

First, let's see how the written configuration file is loaded?

 

 

The source code is very clear, providing a character stream Reader and a byte stream InputStream to load the configuration file ( the purpose of the method overload: to make the user more convenient ), and then go deeper to see the final put Hashtable put (key, value) to set Key-value pair, and finally load the configuration file.

 

 

Then, to see how to get the corresponding value based on the key (put it in, but also consider taking it out)?

 

 

The source code is very clear. The corresponding value is obtained through the parameter key. Considering the convenience of the user, the getProperty method is overloaded. The method marked 2 is returned when the value obtained according to the key is null. The default value (in many scenarios, it is really useful).

 

I know how to load the configuration file, and I know how to get the value corresponding to the key. According to common sense, the project is enough, but sometimes after the project is started, you really need to set additional parameter values, but it does not matter, because Java Having thought of this, the setProperty method is provided to make it possible to set additional parameters.

 

 

If you can use these APIs skillfully in project development, it is enough. Now that the source code has been opened, all the miscellaneous things are mentioned, maybe some APIs can also solve the problems you encounter in other scenarios.

 

 

The Properties class not only provides load for loading configuration, but also provides the ability to write key-value pairs to a file. As shown in the source code above, considering the convenience of the user, the store method is overloaded to provide two ways of store for byte stream OutputStream and character stream Writer.

 

 

As shown in the source code above, in addition to providing support for reading and writing capabilities of conventional configuration files, Properties also provides support for loading and writing xml configuration files.

 

 

As shown in the source code above, the Properties class provides an overloaded list method. In order to facilitate debugging, the list of key-value pairs can be neatly printed out.

 

3. Although simple, it cannot be given to practice everything is nonsense.

Scenario 1: During APM performance monitoring, commonly used APIs for obtaining Java application profile information.

import java.util.Properties;

/**
 * @author Yipei Xiaojian
 */
public class JVMDetails {
    public static void main(String[] args) {
        // Get system information (JDK information, Java virtual machine information, Java provider information, current computer user information)
        Properties properties = System.getProperties();
        // print the system information
        properties.list(System.out);
    }
}

The program runs, and some output screenshots are as follows.

 

 

 

Scenario 2: In business development, let the configuration replace hard coding, and consider the configuration update, the program can read the latest value.

import java.io. *;
import java.util.Hashtable;
import java.util.Properties;

/**
 * Configuration file tools
 * 1. Support to load .properties files and .ini files
 * 2. Support configuration file update
 * @author Yipei Xiaojian
 */
public class PropertiesUtil {

    // private static final Log4j LOG =  .....;

    private static Hashtable<String, PropCache> propCache = new Hashtable<String, PropCache>();

    public static String getString(String propFile, String key) {
        return getString(propFile, key, null);
    }

    public static String getString(String propFile, String key, String defaultValue) {
        if ((!propFile.endsWith(".properties")) && (!propFile.endsWith(".ini"))) {
            propFile = propFile + ".properties";
        }
        PropCache prop = propCache.get(propFile);
        if (prop == null) {
            try {
                prop = new PropCache(propFile);
            } catch (IOException e) {
                // LOG.warn(e);
                System.out.println (String.format ("An error occurred while reading% s", propFile, e));
                return defaultValue;
            }
            propCache.put(propFile, prop);
        }
        String value = prop.getProperty(key, defaultValue);
        if (value != null) {
            value = value.trim();
        }
        return value;
    }

    public static void setString(String propFile, String key, String value)
            throws IOException {
        if ((!propFile.endsWith(".properties")) && (!propFile.endsWith(".ini"))) {
            propFile = propFile + ".properties";
        }
        File file = new File(propFile);
        Properties prop = new Properties();
        try {
            FileInputStream fis = new FileInputStream(file);
            prop.load(fis);
            fis.close();
        } catch (FileNotFoundException e) {
            // LOG.warn(e);
            System.out.println (String.format ("File% s does not exist", propFile));
        }
        FileOutputStream fos = new FileOutputStream(file);
        prop.put(key, value);
        prop.store(fos, null);
        fos.close();
        PropCache localPropCache = propCache.get(propFile);
        if (localPropCache != null) {
            localPropCache.reload();
        }
    }

    private static class PropCache {

        private String fileName;
        private long lastLoad;
        private Properties prop;

        public PropCache(String propFileName) throws IOException {
            File file = new File(propFileName);
            FileInputStream fis = new FileInputStream(file);
            this.prop = new Properties();
            this.prop.load(fis);
            fis.close();
            this.fileName = file.getAbsolutePath();
            this.lastLoad = file.lastModified();
        }

        public String getProperty(String key, String defaultValue) {
            File file = new File(this.fileName);
            if (this.lastLoad < file.lastModified()) {
                reload();
            }
            return this.prop.getProperty(key, defaultValue);
        }

        public void reload() {
            File file = new File(this.fileName);
            try {
                Properties prop = new Properties();
                FileInputStream fis = new FileInputStream(file);
                prop.load(fis);
                fis.close();
                this.prop.clear();
                this.prop.putAll(prop);
                this.lastLoad = file.lastModified();
            } catch (IOException e) {
                // PropertiesUtil.LOG.warn(e);
                System.out.println (String.format ("File% s reloading exception% s", this.fileName, e));
            }
            // PropertiesUtil.LOG.all(new Object[]{this.fileName, " reloaded."});
            System.out.println (String.format ("File% s has been reloaded", this.fileName));
        }
    }
}

Use the jdbc configuration file mentioned at the beginning to verify. Try to get the database type, the default configuration is db2, modify the value of the parameter halfway to mysql, see how effective?

/**
 * Test class
 * @author Yipei Xiaojian
 */
public class M {
    public static void main(String[] args) {
        while(true) {
            System.out.println(PropertiesUtil.getString("db", "jdbc.type"));
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
            }
        }
    }
}

The program runs, and the effect is still very satisfactory.

 

 

 

4. Although it is simple, share a great article with great care.

There are many online sharing about configuration files, but our sharing is not the same.

Our original intention is: to combine actual projects and source code, to talk about the configuration skills used in these years, to help you improve your research and development capabilities (even if it is a loss, even if it is successful).

Its stone can attack jade, I believe it will help you.

In order to help you improve your research and development capabilities (even if it is a loss), follow-up will continue to combine actual projects to see other forms of configuration files used, so stay tuned.

Guess you like

Origin www.cnblogs.com/socoool/p/12683501.html