天天看点

缓存filter及资源池模式

一。缓存过滤器模式

1。概念:缓存过滤器模式是通过使用servlet的filter来动态地缓存生成的页面,从而提高web层的性能和伸缩性。工作原理非常简单,当第一次请求到来时,判断是否可以缓存,可以的话就放在缓存里。当下次请求时,直接从缓存中取出,而不是再次请求。

2。一个简单实现对html页面的缓存:

缓存filter及资源池模式

package cfexample.controller;

缓存filter及资源池模式
缓存filter及资源池模式

import java.io.*;

缓存filter及资源池模式

import javax.servlet.*;

缓存filter及资源池模式

import javax.servlet.http.*;

缓存filter及资源池模式
缓存filter及资源池模式

/**

缓存filter及资源池模式

 *用来替代httpservletreponse的新对象,以提供缓存能力

缓存filter及资源池模式

 */

缓存filter及资源池模式

public class cacheresponsewrapper extends httpservletresponsewrapper {

缓存filter及资源池模式
缓存filter及资源池模式

    private cacheoutputstream outstream;

缓存filter及资源池模式
缓存filter及资源池模式

    //替换outputstream和printwriter

缓存filter及资源池模式

    private servletoutputstream stream;

缓存filter及资源池模式

    private printwriter writer;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    class cacheoutputstream extends servletoutputstream {

缓存filter及资源池模式
缓存filter及资源池模式

        private bytearrayoutputstream bos;

缓存filter及资源池模式
缓存filter及资源池模式

        cacheoutputstream() {

缓存filter及资源池模式

            bos = new bytearrayoutputstream();

缓存filter及资源池模式

        }

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        public void write(int param) throws ioexception {

缓存filter及资源池模式

            bos.write(param);

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        public void write(byte[] b, int off, int len) throws ioexception {

缓存filter及资源池模式

            bos.write(b, off, len);

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        protected byte[] getbytes() {

缓存filter及资源池模式

            return bos.tobytearray();

缓存filter及资源池模式
缓存filter及资源池模式

    }

缓存filter及资源池模式
缓存filter及资源池模式

     public cacheresponsewrapper(httpservletresponse original) {

缓存filter及资源池模式

        super(original);

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    protected servletoutputstream createoutputstream() 

缓存filter及资源池模式

        throws ioexception

缓存filter及资源池模式

    {

缓存filter及资源池模式

        outstream = new cacheoutputstream();

缓存filter及资源池模式

        return outstream;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    public servletoutputstream getoutputstream()

缓存filter及资源池模式

        throws ioexception 

缓存filter及资源池模式
缓存filter及资源池模式

        if (stream != null) {

缓存filter及资源池模式

            return stream;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        if (writer != null) {

缓存filter及资源池模式

            throw new ioexception("writer already in use");

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        stream = createoutputstream();

缓存filter及资源池模式

        return stream;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

     public printwriter getwriter() throws ioexception {

缓存filter及资源池模式
缓存filter及资源池模式

            return writer;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

            throw new ioexception("outputstream already in use");

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        writer = new printwriter(new outputstreamwriter(createoutputstream()));

缓存filter及资源池模式

        return writer;

缓存filter及资源池模式
缓存filter及资源池模式

    protected byte[] getbytes() throws ioexception {

缓存filter及资源池模式

        if (outstream != null) {

缓存filter及资源池模式

            return outstream.getbytes();

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

        return null;

缓存filter及资源池模式
缓存filter及资源池模式

}

缓存filter及资源池模式
缓存filter及资源池模式

//cachefilter.java 过滤器:

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

import java.net.*;

缓存filter及资源池模式

import java.util.*;

缓存filter及资源池模式

import java.text.*;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

import javax.servlet.filter;

缓存filter及资源池模式

import javax.servlet.filterchain;

缓存filter及资源池模式

import javax.servlet.filterconfig;

缓存filter及资源池模式

import javax.servlet.servletcontext;

缓存filter及资源池模式

import javax.servlet.servletexception;

缓存filter及资源池模式

import javax.servlet.servletrequest;

缓存filter及资源池模式

import javax.servlet.servletresponse;

缓存filter及资源池模式

public class cachefilter implements filter {

缓存filter及资源池模式
缓存filter及资源池模式

    private filterconfig filterconfig = null;

缓存filter及资源池模式
缓存filter及资源池模式

    //缓存池

缓存filter及资源池模式

    private hashmap cache;

缓存filter及资源池模式
缓存filter及资源池模式

    public cachefilter() {

缓存filter及资源池模式
缓存filter及资源池模式

    public void dofilter(servletrequest request, 

缓存filter及资源池模式

                         servletresponse response,

缓存filter及资源池模式

                         filterchain chain)

缓存filter及资源池模式

        throws ioexception, servletexception

缓存filter及资源池模式
缓存filter及资源池模式

        httpservletrequest req = (httpservletrequest) request;

缓存filter及资源池模式

        httpservletresponse res = (httpservletresponse) response;

缓存filter及资源池模式
缓存filter及资源池模式

        //缓存子中的键uri+查询字符串

缓存filter及资源池模式

        string key = req.getrequesturi() + "?" + req.getquerystring();

缓存filter及资源池模式
缓存filter及资源池模式

        //只缓存get请求的内容

缓存filter及资源池模式

        if (req.getmethod().equalsignorecase("get") && iscacheable(key)) {

缓存filter及资源池模式

            byte[] data = (byte[]) cache.get(key);

缓存filter及资源池模式
缓存filter及资源池模式

           //池中没有,生成并存入

缓存filter及资源池模式

            if (data == null) {

缓存filter及资源池模式

                cacheresponsewrapper crw = new cacheresponsewrapper(res);

缓存filter及资源池模式

                chain.dofilter(request, crw);

缓存filter及资源池模式

                data = crw.getbytes();

缓存filter及资源池模式

                cache.put(key, data);

缓存filter及资源池模式

            } 

缓存filter及资源池模式
缓存filter及资源池模式

            // 如果有的话,直接得到返回

缓存filter及资源池模式

            if (data != null) {

缓存filter及资源池模式

                res.setcontenttype("text/html");

缓存filter及资源池模式

                res.setcontentlength(data.length);

缓存filter及资源池模式
缓存filter及资源池模式

                try {

缓存filter及资源池模式

                    outputstream os = res.getoutputstream();

缓存filter及资源池模式

                    os.write(data);

缓存filter及资源池模式

                    os.flush();

缓存filter及资源池模式

                    os.close();

缓存filter及资源池模式

                } catch(exception ex) {

缓存filter及资源池模式

                    ex.printstacktrace();

缓存filter及资源池模式

                }

缓存filter及资源池模式

            }

缓存filter及资源池模式

        } else {

缓存filter及资源池模式

            // generate the data normally if it was not cacheable

缓存filter及资源池模式

            chain.dofilter(request, response);

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    //判断是否可以缓存,考虑一个配置文件配置哪些可以缓存,此处省去

缓存filter及资源池模式

    private boolean iscacheable(string key) {

缓存filter及资源池模式

        return true;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    public void init(filterconfig filterconfig) {

缓存filter及资源池模式

        this.filterconfig = filterconfig;

缓存filter及资源池模式
缓存filter及资源池模式

        cache = new hashmap();

缓存filter及资源池模式
缓存filter及资源池模式

    public void destroy() {

缓存filter及资源池模式

        cache.clear();

缓存filter及资源池模式
缓存filter及资源池模式

        cache = null;

缓存filter及资源池模式

        filterconfig = null;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

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

二。资源池模式:

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

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

3。简单实现:

(1)首先一个创建对象的工厂:

缓存filter及资源池模式

package pool;

缓存filter及资源池模式
缓存filter及资源池模式

public interface resourcefactory {

缓存filter及资源池模式

    public object createresource();

缓存filter及资源池模式
缓存filter及资源池模式

    //验证返回的资源,并提供还原

缓存filter及资源池模式

    public boolean validateresource(object o);

缓存filter及资源池模式

(2)资源池:

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

public class resourcepool {

缓存filter及资源池模式

    private resourcefactory factory;

缓存filter及资源池模式
缓存filter及资源池模式

   //参数

缓存filter及资源池模式

    private int maxobjects;

缓存filter及资源池模式

    private int curobjects;

缓存filter及资源池模式

    private boolean quit;

缓存filter及资源池模式
缓存filter及资源池模式

    //出借的资源

缓存filter及资源池模式

    private set outresources;

缓存filter及资源池模式
缓存filter及资源池模式

    //可以使用的资源

缓存filter及资源池模式

    private list inresources;

缓存filter及资源池模式
缓存filter及资源池模式

    public resourcepool(resourcefactory factory, int maxobjects) {

缓存filter及资源池模式

        this.factory = factory;

缓存filter及资源池模式

        this.maxobjects = maxobjects;

缓存filter及资源池模式
缓存filter及资源池模式

        curobjects = 0;

缓存filter及资源池模式
缓存filter及资源池模式

        outresources = new hashset(maxobjects);

缓存filter及资源池模式

        inresources = new linkedlist();

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

   //从池中取资源

缓存filter及资源池模式

    public synchronized object getresource() throws exception {

缓存filter及资源池模式

        while(!quit) {

缓存filter及资源池模式
缓存filter及资源池模式

             if (!inresources.isempty()) {

缓存filter及资源池模式

                object o = inresources.remove(0);

缓存filter及资源池模式
缓存filter及资源池模式

               if(!factory.validateresource(o))

缓存filter及资源池模式

                    o = factory.createresource();

缓存filter及资源池模式
缓存filter及资源池模式

                outresources.add(o);

缓存filter及资源池模式

                return o;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

            //放入出借池

缓存filter及资源池模式

            if(curobjects < maxobjects) {

缓存filter及资源池模式

                object o = factory.createresource();

缓存filter及资源池模式
缓存filter及资源池模式

                curobjects++;

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

            //没有可用的,等待

缓存filter及资源池模式

            try { wait(); } catch(exception ex) {}

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

       //池子已经销毁

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    //归还资源

缓存filter及资源池模式

    public synchronized void returnresource(object o) {

缓存filter及资源池模式
缓存filter及资源池模式

        if(!outresources.remove(o))

缓存filter及资源池模式

            return;

缓存filter及资源池模式
缓存filter及资源池模式

        inresources.add(o);

缓存filter及资源池模式

        notify();

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

    public synchronized void destroy() {

缓存filter及资源池模式

        quit = true;

缓存filter及资源池模式

        notifyall();

缓存filter及资源池模式
缓存filter及资源池模式
缓存filter及资源池模式

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

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