莊周夢蝶

          生活、程序、未來
             :: 首頁 ::  ::  :: 聚合  :: 管理

          緩存filter及資源池模式

          Posted on 2007-02-06 11:47 dennis 閱讀(1389) 評論(0)  編輯  收藏 所屬分類: 模式與架構
          ?一。緩存過濾器模式
          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等等
          主站蜘蛛池模板: 西青区| 密云县| 信宜市| 新蔡县| 宿迁市| 汪清县| 大港区| 临湘市| 五河县| 上饶市| 东乡| 定结县| 呼伦贝尔市| 札达县| 阿城市| 大余县| 大安市| 偏关县| 宁安市| 惠来县| 上林县| 蓬安县| 桃江县| 秭归县| 蓬莱市| 高邑县| 南涧| 隆化县| 镇雄县| 霞浦县| 黄骅市| 登封市| 南汇区| 康马县| 黄浦区| 长岛县| 沁阳市| 荃湾区| 济南市| 云南省| 扎赉特旗|