一。缓存过滤器模式 1。概念:缓存过滤器模式是通过使用servlet的filter来动态地缓存生成的页面,从而提高web层的性能和伸缩性。工作原理非常简单,当第一次请求到来时,判断是否可以缓存,可以的话就放在缓存里。当下次请求时,直接从缓存中取出,而不是再次请求。 2。一个简单实现对html页面的缓存: package cfexample.controller; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; /** *用来替代HttpServletReponse的新对象,以提供缓存能力 */ public class CacheResponseWrapper extends HttpServletResponseWrapper { private CacheOutputStream outStream; //替换OutputStream和PrintWriter private ServletOutputStream stream; private PrintWriter writer; class CacheOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos; CacheOutputStream() { bos = new ByteArrayOutputStream(); } public void write(int param) throws IOException { bos.write(param); } public void write(byte[] b, int off, int len) throws IOException { bos.write(b, off, len); } protected byte[] getBytes() { return bos.toByteArray(); } } public CacheResponseWrapper(HttpServletResponse original) { super(original); } protected ServletOutputStream createOutputStream() throws IOException { outStream = new CacheOutputStream(); return outStream; } public ServletOutputStream getOutputStream() throws IOException { if (stream != null) { return stream; } if (writer != null) { throw new IOException("Writer already in use"); } stream = createOutputStream(); return stream; } public PrintWriter getWriter() throws IOException { if (writer != null) { return writer; } if (stream != null) { throw new IOException("OutputStream already in use"); } writer = new PrintWriter(new OutputStreamWriter(createOutputStream())); return writer; } protected byte[] getBytes() throws IOException { if (outStream != null) { return outStream.getBytes(); } return null; } } //CacheFilter.java 过滤器: package cfexample.controller; import java.io.*; import java.net.*; import java.util.*; import java.text.*; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class CacheFilter implements Filter { private FilterConfig filterConfig = null; //缓存池 private HashMap cache; public CacheFilter() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; //缓存子中的键URI+查询字符串 String key = req.getRequestURI() + "?" + req.getQueryString(); //只缓存get请求的内容 if (req.getMethod().equalsIgnoreCase("get") && isCacheable(key)) { byte[] data = (byte[]) cache.get(key); //池中没有,生成并存入 if (data == null) { CacheResponseWrapper crw = new CacheResponseWrapper(res); chain.doFilter(request, crw); data = crw.getBytes(); cache.put(key, data); } // 如果有的话,直接得到返回 if (data != null) { res.setContentType("text/html"); res.setContentLength(data.length); try { OutputStream os = res.getOutputStream(); os.write(data); os.flush(); os.close(); } catch(Exception ex) { ex.printStackTrace(); } } } else { // generate the data normally if it was not cacheable chain.doFilter(request, response); } } //判断是否可以缓存,考虑一个配置文件配置哪些可以缓存,此处省去 private boolean isCacheable(String key) { return true; } public void init(FilterConfig filterConfig) { this.filterConfig = filterConfig; cache = new HashMap(); } public void destroy() { cache.clear(); cache = null; filterConfig = null; } } 3.实际应用例子:oscache是很好的解决web层缓存的方案!!准备认真读读它的源代码。 二。资源池模式: 1。概念:一个资源池就是一组预先生成的对象,它们可以被出借以便节省多次chuang创建它们所花费的时间。典型的如:EJB池(Service Locator一般都有一个ejb的home接口池),数据库连接池。 2。优点:A。提高了应用的可伸缩性,使资源的创建和开销不至于失控。B,产生了一个统一的有效微调点,通过运行时修改池参数来影响应用的性能等因素。 3。简单实现: (1)首先一个创建对象的工厂: package pool; public interface ResourceFactory { public Object createResource(); //验证返回的资源,并提供还原 public boolean validateResource(Object o); } (2)资源池: package pool; import java.util.*; public class ResourcePool { private ResourceFactory factory; //参数 private int maxObjects; private int curObjects; private boolean quit; //出借的资源 private Set outResources; //可以使用的资源 private List inResources; public ResourcePool(ResourceFactory factory, int maxObjects) { this.factory = factory; this.maxObjects = maxObjects; curObjects = 0; outResources = new HashSet(maxObjects); inResources = new LinkedList(); } //从池中取资源 public synchronized Object getResource() throws Exception { while(!quit) { if (!inResources.isEmpty()) { Object o = inResources.remove(0); if(!factory.validateResource(o)) o = factory.createResource(); outResources.add(o); return o; } //放入出借池 if(curObjects < maxObjects) { Object o = factory.createResource(); outResources.add(o); curObjects++; return o; } //没有可用的,等待 try { wait(); } catch(Exception ex) {} } //池子已经销毁 return null; } //归还资源 public synchronized void returnResource(Object o) { if(!outResources.remove(o)) return; inResources.add(o); notify(); } public synchronized void destroy() { quit = true; notifyAll(); } } 4.实例:很多开源的数据库连接池,ejb模式中的Service Locator等等 |
|