How does java get the content of properties file dynamically in real time
- 2021-11-13 07:30:36
- OfStack
Get the content of properties file dynamically in real time
When you read the properties file with "ClassLoader. getResourceAsStream", you will find that after modification.properties, even if you re-execute it, you will still read in the parameters before modification.
The reason for this problem is that after ClassLoader. getResourceAsStream is read, the. properties is saved in the cache and is read from the cache when re-executed, instead of reading the. properties file again.
Dynamically read code
import java.util.Properties;
/**
* Real-time dynamic acquisition properties The value of the file
* @author Administrator
*
*/
public class demo01 {
/**
* Get the values in the configuration file in real time according to the configuration variables
* @param key Configuration name
* @param filePath The configuration file pathname, for example: test.properties
* @return Configuration value
*/
public static String getCurrentPropertiesValue(String key,String filePath){
String value="";
Properties p = new Properties();
try {
// Non-real-time dynamic acquisition
//p.load(new InputStreamReader(this.class.getClassLoader().getResourceAsStream(filePath), "UTF-8"));
// The following is a dynamic acquisition
String path = Thread.currentThread().getContextClassLoader().getResource("").getPath();
InputStream is = new FileInputStream(path +File.separator+ filePath);
p.load(is);
value=p.getProperty(key);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return value;
}
}
Read configuration file Properties VS ResourceBundle
In java development, For some commonly used configurable information, It is usually stored in a properties file, Because modifying the configuration file does not require recompiling the jar package. For properties files, you can usually use the Properties and ResourceBundle classes to parse. Note that by default, the *. properties file encoding format in the java project is ISO-8859-1, and Properties and ResourceBundle also parse strings in properties files in the ISO-8859-1 format. Therefore, extra attention is needed when parsing familiar files containing Chinese.
ResourceBundle: Usually used to parse the internationalized resource properties file, which automatically selects the corresponding internationalized resource according to the local environment. Properties: Used to parse common properties files
1. Common API
1.1 Properties Common API
Properties inherits Hashtable < Object,Object > Class.
方法签名 | 方法描述 |
---|---|
public String getProperty(String key | 获取属性文件中的Key, 如果key不存在返回Null |
public String getProperty(String key, String defaultValue) | 获取属性文件中key对象的value, 如果key不存在则返回默认值defaultValue |
public Object get(String key) | 父类HashTable中的方法, 返回值类型为Object |
1.2 ResourceBundle Common API
ResourceBundle is an interface that uses PropertyResourceBundle by default to parse properties files.
方法签名 | 方法描述 |
---|---|
public Locale getLocale() | 获取本地国际化环境 |
public Enumeration getKeys() | 获取属性文件中所有key |
public final String getString(String key) | 获取属性文件中key对应的value, 返回值为String, 如果不存在, 则抛出异常 |
public final Object getObject(String key) | 获取属性文件中key对应的value, 返回值为Object, 如果不存在, 则抛出异常 |
2. Properties Parsing Properties File
By default, ISO-8859-1 is used to parse the strings in the configuration file, so it will cause Chinese garbled codes.
2.1 Parsing English Configuration Files
// Default encoding (ISO-8859-1) Read properties file , Chinese garbled code
@Test
public void test_properties_en() throws IOException{
// Properties file location , The relative path is src/main/resources Or src/test/resources, Cannot add classpath:/ Prefix
String propertyFileName = "jdbc.properties";
// Get byte stream
InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
// Create a properties file , And load the file contents
Properties properties = new Properties();
properties.load(is);
String username = properties.getProperty("jdbc.username");
String password = properties.getProperty("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
2.2 Parsing Configuration Files Containing Chinese
By default, ISO-8859-1 is used, and InputStreamReader is converted to UTF8 character stream.
// Specify the encoding method for reading files , Support reading Chinese
@Test
public void test_properties_zh() throws IOException{
// Properties file location , The relative path is src/main/resources Or src/test/resources, Cannot add classpath:/ Prefix
String propertyFileName = "jdbc.properties";
// Get byte stream
InputStream is = getClass().getClassLoader().getResourceAsStream(propertyFileName);
// Convert to UTF-8 Format character stream
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
// Create a properties file , And load the file contents
Properties properties = new Properties();
properties.load(isr);
String username = properties.getProperty("jdbc.username");
String password = properties.getProperty("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
3. ResourceBundle Parsing Properties File
3.1 Parsing English Configuration Files
@Test
public void testRb_en() {
// Resource profile , No need to write file suffix , Default search properties Documents
String bundleName = "jdbc";
// Set the local default environment to English environment
Locale.setDefault(Locale.ENGLISH);
// Specify loading
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
System.out.println("username:" + username + ", password:" + password);
}
3.2 Parsing Configuration Files Containing Chinese
// Processing Chinese
@Test
public void testRb_zh() {
// Resource profile , No need to write file suffix , Default search properties Documents
String bundleName = "jdbc";
// Load the resource profile according to the local default environment
ResourceBundle rb = ResourceBundle.getBundle(bundleName);
String username = iso2Utf8(rb.getString("jdbc.username"));
String password = iso2Utf8(rb.getString("jdbc.password"));
System.out.println("username:" + username + ", password:" + password);
}
/**
* @Description iso Encoded format string is converted to UTF8 Format
* @param str iso Coded string
* @return
* @author zongf
* @date 2019 Year 1 Month 8 Day - Afternoon 3:55:29
*/
private String iso2Utf8(String str) {
if(null == str) return null;
try {
return new String(str.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
4. Properties file
The author created the maven project and used the junit unit test, so the author's configuration file is stored in the src/test/resources directory.
jdbc.properties
jdbc.username= Zhang 3
jdbc.password=123456
jdbc_zh.properties
jdbc.username= Zhang 3
jdbc.password=123456
jdbc_en.properties
jdbc.username=zhangsan
jdbc.password=123456
5. Practical recommendation
The author believes that a well-designed attribute configuration class should be a constant class, which needs to conform to at least two design principles:
The property 1 denier setting cannot be dynamically modified, and the modification method cannot be called even in the compilation environment.
Can be accessed directly through class attributes, without accessing through class objects
Automatically assemble properties without having to manually parse familiar files (available in S140EN with self-annotations or custom annotations)
public class JdbcProperty {
/** User name */
public static final String username;
/** User password */
public static final String password;
// In Spring In application , Automatic assembly with annotations or custom annotations , The author here only aims at 1 Like java Application
static {
// Load properties file
ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
// Initialize properties
username = resourceBundle.getString("jdbc.username");
password = resourceBundle.getString("jdbc.password");
}
}