Properties常用於項目中參數的配置,當項目中某段程序需要獲取動態參數時,就從Properties中讀取該參數,使程序是可配置的、靈活的。
有些配置參數要求立即生效,有些則未必:
一、實時性要求非常高。項目中,有些參數要求實時性非常高,即在系統運行中,IT人員修改了該參數值,該新參數值要求立即在程序中生效;
二、實時性要求不高。其實,並不是每個配置參數都要求實時性那么高,有些配置參數基本不會在項目運行當中修改,或即使在運行當中修改,也只要求其在下一次項目啟動時生效。
針對第二種情況,鑒於程序讀取Properties文件,IO損耗大、效率較低的現狀,我們可以在項目啟動時,預先將Properties的信息緩存起來,以備程序運行當中方便、快捷地使用。
初步想法:在項目啟動加載Listener時,將需要緩存的Properties以鍵值對形式緩存起來。
kick off:
首先,需要一個類存儲Properties,並提供接口實現“緩存Properties”和“讀取Properties”的動作

1 package com.nicchagil.propertiescache; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Hashtable; 6 import java.util.Map; 7 import java.util.Properties; 8 9 import org.apache.log4j.Logger; 10 11 public class PropertiesCacher { 12 13 private static final Logger logger = Logger.getLogger(PropertiesCacher.class); 14 15 // Properties Cache 16 public static Map<String, Properties> pMap = new Hashtable<String, Properties> (); 17 18 /** 19 * Set properties to properties cache 20 * @param pName 21 * @throws IOException 22 */ 23 public static void setProperties(String pName) throws IOException { 24 25 Properties properties = new Properties(); 26 InputStream is = null; 27 28 try { 29 is = PropertiesCacher.class.getResourceAsStream(pName); 30 properties.load(is); 31 32 } finally { 33 34 if (is != null) { 35 is.close(); 36 } 37 38 } 39 40 logger.info("Load to properties cache : " + pName); 41 pMap.put(pName, properties); 42 } 43 44 /** 45 * Get properties by properties path 46 * @param pName 47 * @return 48 */ 49 public static Properties getProperties(String pName) { 50 return pMap.get(pName); 51 } 52 53 /** 54 * Get properties value by properties path & key 55 * @param pName 56 * @param key 57 * @return 58 */ 59 public static String getPropertiesValue(String pName, String key) { 60 if (pMap.get(pName) == null) { 61 return ""; 62 } 63 64 return pMap.get(pName).getProperty(key); 65 } 66 67 }
然后,我們需要在項目啟動時,觸發“緩存Properties”這個動作,這里使用Listener

1 package com.nicchagil.propertiescache; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletContextEvent; 6 import javax.servlet.ServletContextListener; 7 8 import org.apache.log4j.Logger; 9 10 public class PropertiesListener implements ServletContextListener { 11 12 private final Logger logger = Logger.getLogger(PropertiesListener.class); 13 14 @Override 15 public void contextDestroyed(ServletContextEvent event) { 16 17 } 18 19 @Override 20 public void contextInitialized(ServletContextEvent event) { 21 try { 22 // Load config.properties 23 PropertiesCacher.setProperties("/resource/config.properties"); 24 25 // Load log4j.properties 26 PropertiesCacher.setProperties("/log4j.properties"); 27 28 } catch (IOException e) { 29 // TODO Auto-generated catch block 30 31 logger.error(e.getMessage(), e); 32 e.printStackTrace(); 33 } 34 } 35 36 }
作為web項目,配置了Listener,當然需要在web.xml注冊一下了

1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> 3 <display-name>XlsExporterDemo</display-name> 4 <welcome-file-list> 5 <welcome-file>index.html</welcome-file> 6 <welcome-file>index.htm</welcome-file> 7 <welcome-file>index.jsp</welcome-file> 8 <welcome-file>default.html</welcome-file> 9 <welcome-file>default.htm</welcome-file> 10 <welcome-file>default.jsp</welcome-file> 11 </welcome-file-list> 12 <listener> 13 <listener-class>com.nicchagil.propertiescache.PropertiesListener</listener-class> 14 </listener> 15 <servlet> 16 <description></description> 17 <display-name>DebugPropertiesCacheServlet</display-name> 18 <servlet-name>DebugPropertiesCacheServlet</servlet-name> 19 <servlet-class>com.nicchagil.propertiescache.DebugPropertiesCacheServlet</servlet-class> 20 </servlet> 21 <servlet-mapping> 22 <servlet-name>DebugPropertiesCacheServlet</servlet-name> 23 <url-pattern>/DebugPropertiesCacheServlet</url-pattern> 24 </servlet-mapping> 25 </web-app>
最后,自己新建倆properties用於測試,一個是log4j.properties,放在編譯根路徑下;一個是config.properties,放在編譯根路徑的resource文件夾下。key值和value值自定義。
這兩個properties是本人測試用的,當然你也可以用自己滴,但需要相應地修改PropertiesListener的加載動作哦~
dà gōng gào chéng
現在寫一個簡單滴Servlet來測試一下是否能成功讀取,其中這個Servlet在上述滴web.xml一並注冊了,可見“DebugPropertiesCacheServlet”

1 package com.nicchagil.propertiescache; 2 3 import java.io.IOException; 4 import javax.servlet.ServletException; 5 import javax.servlet.http.HttpServlet; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 public class DebugPropertiesCacheServlet extends HttpServlet { 10 private static final long serialVersionUID = 1L; 11 12 public DebugPropertiesCacheServlet() { 13 super(); 14 } 15 16 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 String pfile = request.getParameter("pfile"); 18 String key = request.getParameter("key"); 19 20 if (pfile == null || key == null) { 21 System.out.println(PropertiesCacher.pMap); 22 } 23 24 if (pfile != null && key == null) { 25 System.out.println(PropertiesCacher.getProperties(pfile)); 26 } 27 28 if (pfile != null && key != null) { 29 System.out.println(PropertiesCacher.getPropertiesValue(pfile, key)); 30 } 31 32 } 33 34 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 35 this.doPost(request, response); 36 } 37 38 }
最后,做個簡單的測試,使用瀏覽器分別訪問以下url(其中參數可能需要自行改一下),並查看console是否打印正確滴信息

1 http://localhost:8080/XlsExporterDemo/DebugPropertiesCacheServlet 2 3 http://localhost:8080/XlsExporterDemo/DebugPropertiesCacheServlet?pfile=/resource/config.properties 4 5 http://localhost:8080/XlsExporterDemo/DebugPropertiesCacheServlet?pfile=/resource/config.properties&key=url
Oh year,成功了!!!