zl程序教程

您现在的位置是:首页 >  其他

当前栏目

缓存filter及资源池模式

2023-03-09 22:21:13 时间
一。缓存过滤器模式
1。概念:缓存过滤器模式是通过使用servlet的filter来动态地缓存生成的页面,从而提高web层的性能和伸缩性。工作原理非常简单,当第一次请求到来时,判断是否可以缓存,可以的话就放在缓存里。当下次请求时,直接从缓存中取出,而不是再次请求。
2。一个简单实现对html页面的缓存:
None.gifpackage cfexample.controller;
None.gif
None.gifimport java.io.*;
None.gifimport javax.servlet.*;
None.gifimport javax.servlet.http.*;
None.gif
ExpandedBlockStart.gif/**
InBlock.gif *用来替代HttpServletReponse的新对象,以提供缓存能力
ExpandedBlockEnd.gif 
*/

ExpandedBlockStart.gifpublic class CacheResponseWrapper extends HttpServletResponseWrapper {
InBlock.gif
InBlock.gif    private CacheOutputStream outStream;
InBlock.gif    
InBlock.gif    //替换OutputStream和PrintWriter
InBlock.gif
    private ServletOutputStream stream;
InBlock.gif    private PrintWriter writer;
InBlock.gif    
InBlock.gif   
ExpandedSubBlockStart.gif    class CacheOutputStream extends ServletOutputStream {
InBlock.gif 
InBlock.gif        private ByteArrayOutputStream bos;
InBlock.gif 
ExpandedSubBlockStart.gif        CacheOutputStream() {
InBlock.gif            bos = new ByteArrayOutputStream();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif    
ExpandedSubBlockStart.gif        public void write(int param) throws IOException {
InBlock.gif            bos.write(param);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gif        public void write(byte[] b, int off, int len) throws IOException {
InBlock.gif            bos.write(b, off, len);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gif        protected byte[] getBytes() {
InBlock.gif            return bos.toByteArray();
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gif     public CacheResponseWrapper(HttpServletResponse original) {
InBlock.gif        super(original);
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    protected ServletOutputStream createOutputStream() 
InBlock.gif        throws IOException
ExpandedSubBlockStart.gif    {
InBlock.gif        outStream = new CacheOutputStream();
InBlock.gif        return outStream;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public ServletOutputStream getOutputStream()
InBlock.gif        throws IOException 
ExpandedSubBlockStart.gif    {
ExpandedSubBlockStart.gif        if (stream != null{
InBlock.gif            return stream;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gif        if (writer != null{
InBlock.gif            throw new IOException("Writer already in use");
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        stream = createOutputStream();
InBlock.gif        return stream;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gif     public PrintWriter getWriter() throws IOException {
ExpandedSubBlockStart.gif        if (writer != null{
InBlock.gif            return writer;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gif        if (stream != null{
InBlock.gif            throw new IOException("OutputStream already in use");
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        writer = new PrintWriter(new OutputStreamWriter(createOutputStream()));
InBlock.gif        return writer;
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gif    protected byte[] getBytes() throws IOException {
ExpandedSubBlockStart.gif        if (outStream != null{
InBlock.gif            return outStream.getBytes();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        return null;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif//CacheFilter.java 过滤器:
None.gif
package cfexample.controller;
None.gif
None.gifimport java.io.*;
None.gifimport java.net.*;
None.gifimport java.util.*;
None.gifimport java.text.*;
None.gifimport javax.servlet.*;
None.gifimport javax.servlet.http.*;
None.gif
None.gifimport javax.servlet.Filter;
None.gifimport javax.servlet.FilterChain;
None.gifimport javax.servlet.FilterConfig;
None.gifimport javax.servlet.ServletContext;
None.gifimport javax.servlet.ServletException;
None.gifimport javax.servlet.ServletRequest;
None.gifimport javax.servlet.ServletResponse;
ExpandedBlockStart.gifpublic class CacheFilter implements Filter {
InBlock.gif
InBlock.gif    private FilterConfig filterConfig = null;
InBlock.gif    
InBlock.gif    //缓存池
InBlock.gif
    private HashMap cache;
InBlock.gif    
ExpandedSubBlockStart.gif    public CacheFilter() {
ExpandedSubBlockEnd.gif    }

InBlock.gif    public void doFilter(ServletRequest request, 
InBlock.gif                         ServletResponse response,
InBlock.gif                         FilterChain chain)
InBlock.gif        throws IOException, ServletException
ExpandedSubBlockStart.gif    {
InBlock.gif        HttpServletRequest req = (HttpServletRequest) request;
InBlock.gif        HttpServletResponse res = (HttpServletResponse) response;
InBlock.gif       
InBlock.gif        //缓存子中的键URI+查询字符串
InBlock.gif
        String key = req.getRequestURI() + "?" + req.getQueryString();
InBlock.gif        
InBlock.gif        //只缓存get请求的内容
ExpandedSubBlockStart.gif
        if (req.getMethod().equalsIgnoreCase("get") && isCacheable(key)) {
InBlock.gif            byte[] data = (byte[]) cache.get(key);
InBlock.gif            
InBlock.gif           //池中没有,生成并存入
ExpandedSubBlockStart.gif
            if (data == null{
InBlock.gif                CacheResponseWrapper crw = new CacheResponseWrapper(res);
InBlock.gif                chain.doFilter(request, crw);
InBlock.gif                data = crw.getBytes();
InBlock.gif                cache.put(key, data);
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
InBlock.gif            // 如果有的话,直接得到返回
ExpandedSubBlockStart.gif
            if (data != null{
InBlock.gif                res.setContentType("text/html");
InBlock.gif                res.setContentLength(data.length);
InBlock.gif                
ExpandedSubBlockStart.gif                try {
InBlock.gif                    OutputStream os = res.getOutputStream();
InBlock.gif                    os.write(data);
InBlock.gif                    os.flush();
InBlock.gif                    os.close();
ExpandedSubBlockStart.gif                }
 catch(Exception ex) {
InBlock.gif                    ex.printStackTrace();
ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

ExpandedSubBlockStart.gif        }
 else {
InBlock.gif            // generate the data normally if it was not cacheable
InBlock.gif
            chain.doFilter(request, response);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    //判断是否可以缓存,考虑一个配置文件配置哪些可以缓存,此处省去
ExpandedSubBlockStart.gif
    private boolean isCacheable(String key) {
InBlock.gif        return true;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
ExpandedSubBlockStart.gif    public void init(FilterConfig filterConfig) {
InBlock.gif        this.filterConfig = filterConfig;
InBlock.gif        
InBlock.gif        cache = new HashMap();
ExpandedSubBlockEnd.gif    }

ExpandedSubBlockStart.gif    public void destroy() {
InBlock.gif        cache.clear();
InBlock.gif        
InBlock.gif        cache = null;
InBlock.gif        filterConfig = null;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


3.实际应用例子:oscache是很好的解决web层缓存的方案!!准备认真读读它的源代码。

二。资源池模式:
1。概念:一个资源池就是一组预先生成的对象,它们可以被出借以便节省多次chuang创建它们所花费的时间。典型的如:EJB池(Service Locator一般都有一个ejb的home接口池),数据库连接池。

2。优点:A。提高了应用的可伸缩性,使资源的创建和开销不至于失控。B,产生了一个统一的有效微调点,通过运行时修改池参数来影响应用的性能等因素。

3。简单实现:
(1)首先一个创建对象的工厂:
None.gifpackage pool;
None.gif
ExpandedBlockStart.gifpublic interface ResourceFactory {
InBlock.gif    public Object createResource();
InBlock.gif    
InBlock.gif    //验证返回的资源,并提供还原
InBlock.gif
    public boolean validateResource(Object o);
ExpandedBlockEnd.gif}


(2)资源池:
None.gif
None.gifpackage pool;
None.gif
None.gifimport java.util.*;
None.gif
ExpandedBlockStart.gifpublic class ResourcePool {
InBlock.gif    private ResourceFactory factory;
InBlock.gif    
InBlock.gif   //参数
InBlock.gif
    private int maxObjects;
InBlock.gif    private int curObjects;
InBlock.gif    private boolean quit;
InBlock.gif    
InBlock.gif    //出借的资源
InBlock.gif
    private Set outResources;
InBlock.gif    
InBlock.gif    //可以使用的资源
InBlock.gif
    private List inResources;
InBlock.gif    
ExpandedSubBlockStart.gif    public ResourcePool(ResourceFactory factory, int maxObjects) {
InBlock.gif        this.factory = factory;
InBlock.gif        this.maxObjects = maxObjects;
InBlock.gif        
InBlock.gif        curObjects = 0;
InBlock.gif        
InBlock.gif        outResources = new HashSet(maxObjects);
InBlock.gif        inResources = new LinkedList();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif   //从池中取资源
ExpandedSubBlockStart.gif
    public synchronized Object getResource() throws Exception {
ExpandedSubBlockStart.gif        while(!quit) {
InBlock.gif        
ExpandedSubBlockStart.gif             if (!inResources.isEmpty()) {
InBlock.gif                Object o = inResources.remove(0);
InBlock.gif                
InBlock.gif               if(!factory.validateResource(o))
InBlock.gif                    o = factory.createResource();
InBlock.gif                
InBlock.gif                outResources.add(o);
InBlock.gif                return o;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            //放入出借池
ExpandedSubBlockStart.gif
            if(curObjects < maxObjects) {
InBlock.gif                Object o = factory.createResource();
InBlock.gif                outResources.add(o);
InBlock.gif                curObjects++;
InBlock.gif                
InBlock.gif                return o;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            //没有可用的,等待
ExpandedSubBlockStart.gif
            try { wait(); } catch(Exception ex) {}
ExpandedSubBlockEnd.gif        }

InBlock.gif    
InBlock.gif       //池子已经销毁
InBlock.gif
        return null;
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    //归还资源
ExpandedSubBlockStart.gif
    public synchronized void returnResource(Object o) {
InBlock.gif        
InBlock.gif        if(!outResources.remove(o))
InBlock.gif            return;
InBlock.gif        
InBlock.gif        inResources.add(o);
InBlock.gif        notify();
ExpandedSubBlockEnd.gif    }

InBlock.gif    
ExpandedSubBlockStart.gif    public synchronized void destroy() {
InBlock.gif        quit = true;
InBlock.gif        notifyAll();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


4.实例:很多开源的数据库连接池,ejb模式中的Service Locator等等

文章转自庄周梦蝶  ,原文发布5.16