When configuring resources such as data sources or FTP servers, we can place these configuration information into an independent external attribute file and refer to attribute items in the attribute file through placeholders such as ${user} and ${password} in the Spring configuration file.
This configuration has two benefits:
Spring provides a PropertyPlaceholderConfigurer that is able to reference external properties files when loading a bean. PropertyPlaceholderConfigurer implements the BeanFactoryPostProcessorBean interface, so it is a Bean factory postprocessor.
1 Basic Quote
1.1 PropertyPlaceholderConfigurer method (XML configuration)
Suppose you need to define a data source in the bean:
<bean id="dataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://127.0.0.1:3306/spring4" p:username="root" p:password=""/>
Here, the driver class name, JDBC URL, and database username and password are written directly in XML. In this way, if you need to change the database configuration information during deployment, you need to first find the XML and then modify it, which is inconvenient.
It is recommended to extract this information into a configuration file, assuming the name is system.priperties:
driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/spring4username=rootpassword=
The attribute file can define multiple attributes, and the format of each attribute is:属性名=属性值
Spring configuration:
<!-- Introduce external properties file--><bean p:location="classpath:system.properties" p:fileEncoding="utf-8"/><!-- Data source--><bean id="dataSource" destroy-method="close" p:driverClassName="${driverClassName}" p:url="${url}" p:username="${username}" p:password="${password}"/>After this configuration, we only need to pay attention to this configuration file when deploying.
PropertyPlaceholderConfigurer property description is as follows:
| property | illustrate |
|---|---|
| location | Specifies the path to the property file. |
| locations | Specifies the path to multiple attribute files. |
| fileEncoding | The encoding format of the file. If not specified, Spring will use the operating system's default encoding format to read the contents of the file. |
| Order | If multiple PropertyPlaceholderConfigurers are defined in the configuration file, you can specify the priority order through this property. |
| placeholderPrefix | Placeholder suffix, default is ${. |
| placeholderSuffix | Placeholder prefix, default is }. |
1.2 context:property-placehoder method (XML configuration)
You can use the context namespace to define the property file, which is more elegant than the configuration method of PropertyPlaceholderConfigurer.
<context:property-placeholder location="classpath:system.properties" file-encoding="utf-8"/>
Although this method requires the property to be encrypted or the advanced functions of using database tables to save configuration information, the PropertyPlaceholderConfigurer class must be extended, and then the Bean configuration method mentioned earlier is adopted.
1.3 @value method (based on annotation or JAVA class configuration)
An annotated beans can automatically inject property values into the member variables or methods of the bean annotated by @Value.
@Componentpublic class CustomDataSource { @Value("${driverClassName}") private String driverClassName; @Value("${url}") private String url; @Value("${username}") private String username; @Value("${password}") private String password; //omit getter/setter}The class that annotates @Configuration based on JAVA class itself annotates @Component, so its reference method is the same as the reference method based on annotation configuration.
Note: During use, make sure that the referenced attribute value exists in the attribute file and the type matches, otherwise an exception will be thrown.
2 Encryption attribute value
For insensitive attribute information, it is reasonable to appear in plain text in the attribute file, but if the attribute information is sensitive information (such as database username and password, etc.), it is recommended to save it in ciphertext. Because if the sensitive information is stored ciphertext, then anyone with server login permission may see confidential information, which will affect system security.
For systems that require particularly high security requirements (banks, public security systems, etc.), this sensitive information should only be in the hands of a few specific maintenance personnel. Therefore, we need to encrypt this information, and then decrypt the file after the Spring container reads the file.
PropertyPlaceholderConfigurer inherits from the PlaceholderConfigurerSupport class, which designs methods to convert properties before they are used:
| method | illustrate |
|---|---|
| convertProperty(String propertyName, String propertyValue) | When each property value is loaded and read, this method is called to convert it. |
| String convertPropertyValue(String originalValue) | It is similar to the previous method, except that the parameters are only passed in the attribute value. |
| void convertProperties(Properties props) | Convert all attribute values. |
By default, these three are empty methods. We can extend PropertyPlaceholderConfigurer to override the corresponding conversion methods, thereby supporting encrypted property value files.
2.1 DES encryption and decryption tool class
The encryption of information is divided into two ways: symmetric and asymmetric. Symmetrically means that the encrypted information can be decrypted, while the asymmetric method cannot be decrypted as the original value based on the encrypted information. MD5 belongs to asymmetric encryption, and DES belongs to symmetric encryption. So here we use DES to encrypt the attribute value; when reading the attribute value, then use DES to decrypt it.
Please click here for the source code of DES encryption and decryption tool.
DES encryption and decryption instructions:
We use the DES encryption and decryption tool to encrypt the database account and password through the command line; then write the encrypted string to system.properties, which is as follows:
username=q5L+2PPrsPQ=password=UdyjsvkXc/Q=
2.2 Encrypt the value of the attribute file
First, customize the attribute configurator, which supports decryption conversion:
public class CustomPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer { /** * DES key*/ private static final String KEY_STR = "123456"; /** * Value encrypted property name group*/ public static final String[] ENCRYPT_PROPERTY_NAMES = new String[]{"username", "password"}; @Override protected String convertProperty(String propertyName, String propertyValue) { if (!isDecrypt(propertyName)) { return propertyValue; } //Decrypt return new DES(KEY_STR).decrypt(propertyValue); } /** * Is it necessary to decrypt* * @param propertyName PropertyName PropertyName */ private boolean isDecrypt(String propertyName) { return ArrayUtils.contains(ENCRYPT_PROPERTY_NAMES, propertyName); }}Notice:
Then configure the custom attribute file through <bean>:
<bean p:location="classpath:system.properties" p:fileEncoding="utf-8"/>
In this way, the Spring container can load the encrypted attribute files. Isn't it very simple?
O(∩_∩)O Haha~
3 Quotations to oneself
Spring allows reference to the value of the attribute through ${propName} in the Bean definition, and also allows the use of ${propName} to implement mutual references between attributes in the property file.
database=spring4driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://127.0.0.1:3306/${database}Here, the value of another attribute (database instance name) is referenced through ${database}. Therefore, for some complex properties, we can extract the changes in the properties in this way to minimize the configuration.
Note: If a property value is too long, we can add "/" to the end of each line, and divide the property value into multiple lines, just like this:
profile.jdbc.url=jdbc:mysql://127.0.0.1:3306/dbName?useUnicode=true&characterEncoding/ =UTF-8/ &zeroDateTimeBehavior=convertToNull
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.