1. Background
Recently, during the project development process, I encountered the problem that I needed to define some custom variables in the properties file for dynamic reading and changing the variables of Java programs, and no longer needed to modify the code. I took this opportunity to sort out and analyze the content of properties file in the integrated development project of Spring+SpringMVC+Mybatis through Java programs, and share it with you first.
2. Project environment introduction
Three or five ways to implement it
Method 1. Load the contents in the configuration file jdbc.properties through context:property-placeholder
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
The above configuration is equivalent to the following configuration, which is a simplification of the following configuration
<bean id="propertyConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="locations"> <list> <value>classpath:jdbc.properties</value> </list> </property></bean>
Note: In this way, if you have the following configuration in the spring-mvc.xml file, you must not be missing the following red part, about its function and principle.
<!-- Configure component scanning, only Controller annotations are scanned in springmvc container--><context:component-scan base-package="com.hafiz.www" use-default-filters="false"> <context:include-filter type="annotation" expression="org.springframework.steretype.Controller"/></context:component-scan>
Method 2. Injection using annotations, mainly injecting the corresponding value in properties file using annotations in Java code.
<bean id="prop"> <!-- This is the PropertiesFactoryBean class. It also has a locations property, which also receives an array, just like the above--> <property name="locations"> <array> <value>classpath:jdbc.properties</value> </array> </property></bean>
Method 3. Use the util:properties tag to expose the contents in the properties file
<util:properties id="propertiesReader" location="classpath:jdbc.properties"/>
Note: Using the above line configuration, you need to declare the following red part in the header of the spring-dao.xml file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
Method 4. Expose properties to the properties of the custom subclass for use in the program when loading the context through PropertyPlaceholderConfigurer
<bean id="propertyConfigurer"> <property name="ignoreUnresolvablePlaceholders" value="true"/> <property name="ignoreResourceNotFound" value="true"/> <property name="locations"> <list> <value>classpath:jdbc.properties</value> </list> </property></bean>
The declaration of the custom class PropertyConfigurer is as follows:
package com.hafiz.www.util;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;import java.util.Properties;/** * Desc:properties configuration file reading class* Created by hafiz.zhang on 2016/9/14. */public class PropertyConfigurer extends PropertyPlaceholderConfigurer { private Properties props; // Access the properties configuration file key-value result @Override protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException { super.processProperties(beanFactoryToProcess, props); this.props = props; } public String getProperty(String key){ return this.props.getProperty(key); } public String getProperty(String key, String defaultValue) { return this.props.getProperty(key, defaultValue); } public Object setProperty(String key, String value) { return this.props.setProperty(key, value); }}How to use: Just use @Autowired annotation injection in the class you need to use.
Method 5. Customize the tool class PropertyUtil, and read the properties file content in the static static code block of the class and save it in the static property for use by other programs.
package com.hafiz.www.util;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.*;import java.util.Properties;/** * Desc:properties file acquisition tool class* Created by hafiz.zhang on 2016/9/15. */public class PropertyUtil { private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class); private static Properties props; static{ loadProps(); } synchronized static private void loadProps(){ logger.info("Start loading properties file contents......"); props = new Properties(); InputStream in = null; try { <!--First type, obtain properties file stream through the class loader--> in = PropertyUtil.class.getClassLoader().getResourceAsStream("jdbc.properties"); <!--Second type, obtain properties file stream through the class--> //in = PropertyUtil.class.getResourceAsStream("/jdbc.properties"); props.load(in); } catch (FileNotFoundException e) { logger.error("jdbc.properties file not found"); } catch (IOException e) { logger.error("IOException appears"); } finally { try { if(null != in) { in.close(); } } catch (IOException e) { logger.error("Exception closed with jdbc.properties file stream closed"); } } logger.info("Loading the content of the properties file........."); logger.info("Properties file content: " + props); } public static String getProperty(String key){ if(null == props) { loadProps(); } return props.getProperty(key); } public static String getProperty(String key, String defaultValue) { if(null == props) { loadProps(); } return props.getProperty(key, defaultValue); }}Note: In this way, when the class is loaded, it will automatically read the configuration file content in the specified location and save it to static properties, which is efficient and convenient, and can be loaded at one time and used multiple times.
4. Precautions and suggestions
The first three methods are rigid in the above five methods. And if you want to use them in a bean with @Controller annotation, you need to declare them in SpringMVC's configuration file spring-mvc.xml. If you want to use them in a bean with @Service, @Respository, etc., you need to declare them in spring.xml in Spring's configuration file.
I personally recommend the fourth and fifth configuration methods. The fifth is the best. It does not even need to be injected into the tool-like object, and it directly calls the static method for acquisition, and it only loads it once, which is also highly efficient. Moreover, the first three methods are not very flexible, and the key value of @Value is required.
5. Test to verify whether it is available
1. First we create PropertiesService
package com.hafiz.www.service;/** * Desc:java program gets the service of the content of the properties file * Created by hafiz.zhang on 2016/9/16. */public interface PropertiesService { /** * The first implementation method gets the value of the specified key in the properties file * * @return */ String getProperyByFirstWay(); /** * The second implementation method gets the value of the specified key in the properties file * * @return */ String getProperyBySecondWay(); /** * The third implementation method gets the value of the specified key in the properties file * * @return */ String getProperyByThirdWay(); /** * The fourth implementation method gets the value of the specified key in the properties file * * @param key * * @return */ String getProperyByFourthWay(String key); /** * The fourth implementation method gets the value of the specified key in the properties file * * @param key * * @param defaultValue * * @return */ String getProperyByFourthWay(String key, String defaultValue); /** * The fifth implementation method gets the value of the specified key in the properties file * * @param key * * @return */ String getProperyByFifthWay(String key); /** * The fifth implementation method to get the value of the specified key in the properties file * * @param key * * @param defaultValue * * @return */ String getProperyByFifthWay(String key, String defaultValue);}2. Create and implement the class PropertiesServiceImpl
package com.hafiz.www.service.impl;import com.hafiz.www.service.PropertiesService;import com.hafiz.www.util.PropertyConfigurer;import com.hafiz.www.util.PropertyUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Service;/** * Desc: Java program obtains the service implementation class of the service that obtains the content of the properties file* Created by hafiz.zhang on 2016/9/16. */@Servicepublic class PropertiesServiceImpl implements PropertiesService { @Value("${test}") private String testDataByFirst; @Value("#{prop.test}") private String testDataBySecond; @Value("#{propertiesReader[test]}") private String testDataByThird; @Autowired private PropertyConfigurer pc; @Override public String getProperyByFirstWay() { return testDataByFirst; } @Override public String getProperyBySecondWay() { return testDataBySecond; } @Override public String getProperyByThirdWay() { return testDataByThird; } @Override public String getProperyByFourthWay(String key) { return pc.getProperty(key); } @Override public String getProperyByFourthWay(String key, String defaultValue) { return pc.getProperty(key, defaultValue); } @Override public String getProperyByFifthWay(String key) { return PropertyUtil.getPropery(key); } @Override public String getProperyByFifthWay(String key, String defaultValue) { return PropertyUtil.getProperty(key, defaultValue); }}3. Controller class PropertyController
package com.hafiz.www.controller;import com.hafiz.www.service.PropertiesService;import com.hafiz.www.util.PropertyUtil;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;/** * Desc:properties test controller* Created by hafiz.zhang on 2016/9/16. */@Controller@RequestMapping("/prop")public class PropertyController { @Autowired private PropertiesService ps; @RequestMapping(value = "/way/first", method = RequestMethod.GET) @ResponseBody public String getPropertyByFirstWay(){ return ps.getProperyByFirstWay(); } @RequestMapping(value = "/way/second", method = RequestMethod.GET) @ResponseBody public String getPropertyBySecondWay(){ return ps.getProperyBySecondWay(); } @RequestMapping(value = "/way/third", method = RequestMethod.GET) @ResponseBody public String getPropertyByThirdWay(){ return ps.getProperyByThirdWay(); } @RequestMapping(value = "/way/fourth/{key}", method = RequestMethod.GET) @ResponseBody public String getPropertyByFourthWay(@PathVariable("key") String key){ return ps.getProperyByFourthWay(key, "defaultValue"); } @RequestMapping(value = "/way/fifth/{key}", method = RequestMethod.GET) @ResponseBody public String getPropertyByFifthWay(@PathVariable("key") String key){ return PropertyUtil.getProperty(key, "defaultValue"); }}4.jdbc.properties file
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://192.168.1.196:3306/dev?useUnicode=true&characterEncoding=UTF-8jdbc.username=rootjdbc.password=123456jdbc.maxA ctive=200jdbc.minIdle=5jdbc.initialSize=1jdbc.maxWait=60000jdbc.timeBetweenEvictionRunsMillis=60000jdbc.minEvictableIdleTimeMillis=300000jdbc.validationQuery=select 1 from t_userjdbc.testWhileIdle=truejdbc.testOnReturn=falsejdbc.poolPreparedStatements=truejdbc.maxPoolPreparedStatementPerConnectionSize=20jdbc.filters=stat#test datatest=com.hafiz.www
5. Project result diagram
6. Project download: demo http://xiazai.VeVB.COM/201612/yuanma/propertiesConfigurer_jb51.zip
7. Test results
The first method
The second way
The third way
The fourth method
The fifth method
6. Summary
Through this review and testing, we understand the role and principle of the parent-child container relationship between Spring and SpringMVC and the use-default-filters attribute that is most easily overlooked when scanning the context:component-scan tag package. Be able to better locate and quickly solve the problems encountered again. Anyway, great~~~
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.