一。缓存过滤器模式
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等等
文章转自庄周梦蝶 ,原文发布5.16