缓存filter及资源池模式

    xiaoxiao2024-03-23  133

    一。缓存过滤器模式 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

    最新回复(0)