首先我的配置文件名稱:cdsssms.properties,內容如下:
ORDER_URL=http://xx.xx.x.x:8888/sms.aspx
USER_ID=311147
ACCOUNT_NO=kp11l
ACCOUNT_PASSWORD=10003451
1、第一種使用文件流方式讀取。
讀取多個properties文件的例子。此例子直接可以用於到項目中。
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
*
* @Description:Properties配置文件工具
*
*/
public class ConfigUtil {
private static Logger logger = LoggerFactory.getLogger(ConfigUtil.class);//日誌
final static Properties props = new Properties();//配置文件對象
static String rootPath= "";
/**加密項目的文件路徑**/
public static final String IMAGEURl = ConfigUtil.getGetProperties("parameter").getProperty("imagePath").toString();
public static final String PAGE_DIR = ConfigUtil.getGetProperties("parameter").getProperty("pageDir").toString();
public static final String CLASS_DIR = ConfigUtil.getGetProperties("parameter").getProperty("classDir").toString();
public static final String PROJECT_NAME = ConfigUtil.getGetProperties("parameter").getProperty("projectName").toString();
public static final String PROJECT_URL = ConfigUtil.getGetProperties("parameter").getProperty("projectUrl").toString();
/**短信通道的參數**/
public static final String ORDER_URL = ConfigUtil.getGetProperties("cdsssms").getProperty("ORDER_URL").toString();
public static final String USER_ID = ConfigUtil.getGetProperties("cdsssms").getProperty("USER_ID").toString();
public static final String ACCOUNT_NO = ConfigUtil.getGetProperties("cdsssms").getProperty("ACCOUNT_NO").toString();
public static final String ACCOUNT_PASSWORD = ConfigUtil.getGetProperties("cdsssms").getProperty("ACCOUNT_PASSWORD").toString();
/**
*
* @Description:得到Properties配置文件
* @param propertiesName(配置文件路徑)
* @param programName 項目名
* @throws
*/
public static Properties getGetProperties(String propertiesName, String programName){
String url = getUrl(programName);
setPro(url, propertiesName);
return props;
}
/**
*
* @Title: getGetPropertiesByClass
* @Description: 通過class類得到當前配置文件路徑
* @param cls
* @param propertiesName
* @return Properties
* @author ganjing
* @throws
*/
public static Properties getGetPropertiesByClass(Class<?> cls, String propertiesName){
String url = getClassUrl(cls);
setPro(url, propertiesName);
return props;
}
/**
*
* @Description:得到Properties配置文件
* @param propertiesName 配置文件中的屬性名稱
* @return Properties
* @throws
*/
public static Properties getGetPropertiesForJar(String propertiesName){
String url = getUrlForJar();
setPro(url, propertiesName);
return props;
}
/**
*
* @Description: 獲得classpath基礎路徑
*
* @return
*/
private static String getUrl(String programName) {
rootPath = ConfigUtil.class.getResource("").toString();
String url = null;
if (System.getProperty("os.name").toLowerCase().indexOf("window") > -1) {
url = rootPath.replace("file:/", "").replace("%20", " ")
.split("/com")[0];
} else {
url = rootPath.replace("file:", "").replace("%20", " ")
.split("/com")[0];
}
String separator = "/";
String url1 = url.substring(0, url.lastIndexOf(separator));
String url2 = url.substring(url1.lastIndexOf(separator), url1.length());
url1 = url1.substring(0, url1.lastIndexOf(separator));
url1 = url1.substring(0, url1.lastIndexOf(separator));
String url3 = url.substring(url.lastIndexOf(separator), url.length());
return url1 + File.separator + programName+ url2+url3;
}
private static String getClassUrl(Class<?> cls) {
return cls.getClassLoader().getResource("").getPath();
}
/**
*
* @author jl
* @Description: 返回jar運行同級目錄config
* @date:2017年3月13日 下午4:21:00
* @return
*/
private static String getUrlForJar() {
return "config";
}
/**
*
* @Description: 獲得properties文件
* @date:2017年3月13日 下午4:26:36
*/
private static void setPro(String url, String propertiesName) {
FileInputStream fileIo = null;
BufferedInputStream bufferIo = null;
try {
fileIo = new FileInputStream(url+File.separator+propertiesName+".properties");
bufferIo = new BufferedInputStream(fileIo);
props.load(bufferIo);
} catch (Exception e) {
logger.error("讀取項目的配置文件加載異常:{}",e);
} finally {
try {
fileIo.close();
bufferIo.close();
} catch (IOException e) {
logger.error("讀取項目的配置文件加載異常:{}",e);
try {
bufferIo.close();
} catch (IOException e1) {
logger.error("讀取項目的配置文件加載異常:{}",e1);
}
}
}
}
/**
*
* @Description:得到Properties配置文件
* @param propertiesName 配置文件的名稱
* @return Properties 配置文件中的數據
* @throws
*/
public static Properties getGetProperties(String propertiesName){
rootPath = ConfigUtil.class.getResource("").toString();
String url = null;
if (System.getProperty("os.name").toLowerCase().indexOf("window") > -1) {
url = rootPath.replace("file:/", "").replace("%20", " ")
.split("/com")[0];
} else {
url = rootPath.replace("file:", "").replace("%20", " ")
.split("/com")[0];
}
FileInputStream fileIo = null;
BufferedInputStream bufferIo = null;
try {
fileIo = new FileInputStream(url+File.separator+propertiesName+".properties");
bufferIo = new BufferedInputStream(fileIo);
props.load(bufferIo);
} catch (Exception e) {
logger.error("讀取項目的配置文件加載異常:{}",e);
} finally {
try {
fileIo.close();
bufferIo.close();
} catch (IOException e) {
logger.error("讀取項目的配置文件加載異常:{}",e);
try {
bufferIo.close();
} catch (IOException e1) {
logger.error("讀取項目的配置文件加載異常:{}",e1);
}
}
}
return props;
}
}
要看更詳細的原理介紹請參考鏈接地址:https://www.cnblogs.com/super-yu/p/8622463.html
2、第二種使用PropertyPlaceHolderConfigurer
spring項目的配置文件具體配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 使用註解注入properties中的值 -->
<bean id="SDKConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- ignoreUnresolvablePlaceholders爲是否忽略不可解析的 Placeholder,如配置了多個PropertyPlaceholderConfigurer,則需設置爲true -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:/config/${package.env}/mobile.properties</value>
<value>classpath:/config/${package.env}/db.properties</value>
<value>classpath:/config/${package.env}/cdsssms.properties</value>
</list>
</property>
<!-- 設置編碼格式 -->
<property name="fileEncoding" value="UTF-8"></property>
</bean>
</beans>
開始我把@Value("${msg.send.url}")用在controller的一個類中使用。報錯:
Error creating bean with name 'creditCardPaymentController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private java.lang.String com.qingyu.pay.mobile.controller.CreditCardPaymentController.smsOrderUrl;
根據報錯:在我的creditCardPaymentController中短信配置文件注入失敗,證明spring加載配置文件都沒有加載成功。然後查檢項目的配置文件:
<context:component-scan base-package="com.xxxxx.xxx">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
發現我沒有把controller包放入component-scan中掃描。所以報此錯。一般配置文件的使用引入到Service層中使用。所以我創建了一個Service類,代碼如下:
@Service("sendMsgService")
public class SendMsgService {
private static final Logger logger = LoggerFactory.getLogger(SendMsgService.class);
@Value("${ORDER_URL}")
private String smsOrderUrl;
@Value("${USER_ID}")
private String smsUserID;
@Value("${ACCOUNT_NO}")
private String smsAccountNo;
@Value("${ACCOUNT_PASSWORD}")
private String smsPassword;
public String sendSmsRequest(){
logger.info("短信發送的userId:{},accountNo:{},password:{},url:{}",smsUserID,smsAccountNo,smsPassword,smsOrderUrl);
return "";
}
}
要深入瞭解PropertyPlaceHolderConfigurer的實現原理請參考以下blog:
https://www.cnblogs.com/fnlingnzb-learner/p/10384742.html
https://blog.csdn.net/u013789656/article/details/80937687
https://blog.csdn.net/CSDN19951017/article/details/84031375
3、第三種使用PropertiesFactoryBean
使用格式:@Value("#{SDKConfig['xf.payDF.url']}")
spring項目配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 使用註解注入properties中的值 -->
<bean id="SDKConfig" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<array>
<value>classpath:xf-sdk.properties</value>
<value>classpath:xfx-sdk.properties</value>
<value>classpath:dd-sdk.properties</value>
<value>classpath:prop.properties</value>
</array>
</property>
<!-- 設置編碼格式 -->
<property name="fileEncoding" value="UTF-8"></property>
</bean>
</beans>
Service類的代碼:
@Service("sendMsgService")
public class SendMsgService {
private static final Logger logger = LoggerFactory.getLogger(SendMsgService.class);
@Value("#{SDKConfig['ORDER_URL']}")
private String smsOrderUrl;
@Value("#{SDKConfig['USER_ID']}")
private String smsUserID;
@Value("#{SDKConfig['ACCOUNT_NO']}")
private String smsAccountNo;
@Value("#{SDKConfig['ACCOUNT_PASSWORD']}")
private String smsPassword;
public String sendSmsRequest(){
logger.info("短信發送的userId:{},accountNo:{},password:{},url:{}",smsUserID,smsAccountNo,smsPassword,smsOrderUrl);
return "";
}
}
參考鏈接代碼:https://blog.csdn.net/qq_1017097573/article/details/62897645
總結:PropertyPlaceholderConfigurer 與PropertiesFactoryBean 區別:
使用 PropertyPlaceholderConfigurer 時, @Value表達式的用法是 @Value(value="${properties key}") ,
使用 PropertiesFactoryBean 時,我們還可以用@Value 讀取 properties對象的值, @Value 用法 是 @Value(value="#{configProperties['properties key']}")