单例模式的使用场景
单例模式
我曾经做过一个文件上传的功能,文件上传需要限制的文件大小,文件类型等等都可以使用properties去设置,这个思想可以参照数据库连接池的配置,每当我们的客户进行文件上传的时候,我们都必须提取这个peoperties文件中的属性来使用,当我们提取出来后存放在内存中时,这个时候问题产生了,如果每次请求过来都需要创建一个对象的话,内存消耗会很大,我们只要把这个对象设计成单例就可以了。那么每次拿出来的时候,都会只拿到这一个对象了,但是要注意多线程并发的线程安全问题。
工程结构:
1)创建单例模式的类封装properties的属性值
1 package com.sky.util; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 public class PropertiesUtil { 7 private Map<String, String> properties = new HashMap<String, String>(); 8 9 private static PropertiesUtil instance = new PropertiesUtil(); 10 11 private PropertiesUtil(){} 12 13 public static PropertiesUtil getInstance(){ 14 return instance; 15 } 16 17 public void addProperty(String propertyName, String propertyValue){ 18 properties.put(propertyName, propertyValue); 19 } 20 21 public String getProperty(String propertyName){ 22 return properties.get(propertyName); 23 } 24 }
2)创建监听器初始化properties文件并将参数传给PropertiesUtil类
1 package com.sky.listener; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.util.Map; 6 import java.util.Properties; 7 8 import javax.servlet.ServletContextEvent; 9 import javax.servlet.ServletContextListener; 10 11 import com.sky.util.PropertiesUtil; 12 13 public class FileUploadListener implements ServletContextListener{ 14 15 @Override 16 public void contextDestroyed(ServletContextEvent arg0) { 17 18 } 19 20 @Override 21 public void contextInitialized(ServletContextEvent arg0) { 22 InputStream in = getClass().getClassLoader().getResourceAsStream("/info.properties"); 23 24 Properties properties = new Properties(); 25 try { 26 properties.load(in); 27 28 for(Map.Entry<Object, Object> prop: properties.entrySet()){ 29 String propertyName = (String) prop.getKey(); 30 String propertyValue = (String) prop.getValue(); 31 32 PropertiesUtil.getInstance().addProperty(propertyName, propertyValue); 33 } 34 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 } 39 40 }
3)创建servlet测试参数是否正确
1 package com.sky.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServlet; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 import com.sky.util.PropertiesUtil; 11 12 public class FileUplodServlet extends HttpServlet{ 13 /** 14 * 15 */ 16 private static final long serialVersionUID = -3372491275711404747L; 17 18 @Override 19 protected void doPost(HttpServletRequest request, HttpServletResponse response) 20 throws ServletException, IOException { 21 String exts = PropertiesUtil.getInstance().getProperty("exts"); 22 String Maxsize = PropertiesUtil.getInstance().getProperty("file.max.size"); 23 String totalMaxSize = PropertiesUtil.getInstance().getProperty("total.file.max.size"); 24 25 System.out.println("exts : " + exts); 26 System.out.println("Maxsize : " + Maxsize); 27 System.out.println("totalMaxSize : " + totalMaxSize); 28 } 29 }
4)web.xml的配置
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app version="3.0" 3 xmlns="http://java.sun.com/xml/ns/javaee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 6 http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 7 <display-name></display-name> 8 <welcome-file-list> 9 <welcome-file>index.jsp</welcome-file> 10 </welcome-file-list> 11 <listener> 12 <listener-class>com.sky.listener.FileUploadListener</listener-class> 13 </listener> 14 <servlet> 15 <servlet-name>upload</servlet-name> 16 <servlet-class>com.sky.servlet.FileUplodServlet</servlet-class> 17 </servlet> 18 <servlet-mapping> 19 <servlet-name>upload</servlet-name> 20 <url-pattern>/upload</url-pattern> 21 </servlet-mapping> 22 </web-app>
5)发布验证结果
单例模式往往在于你只需要一个对象,例如windows的task窗口,我往往喜欢使用单例来节约对象,这也算是多种设计模式中最简单的一种了。