莊周夢(mèng)蝶

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

          緩存filter及資源池模式

          Posted on 2007-02-06 11:47 dennis 閱讀(1388) 評(píng)論(0)  編輯  收藏 所屬分類: 模式與架構(gòu)
          ?一。緩存過濾器模式
          1。概念:緩存過濾器模式是通過使用servlet的filter來動(dòng)態(tài)地緩存生成的頁面,從而提高web層的性能和伸縮性。工作原理非常簡單,當(dāng)?shù)谝淮握?qǐng)求到來時(shí),判斷是否可以緩存,可以的話就放在緩存里。當(dāng)下次請(qǐng)求時(shí),直接從緩存中取出,而不是再次請(qǐng)求。
          2。一個(gè)簡單實(shí)現(xiàn)對(duì)html頁面的緩存:
          package?cfexample.controller;

          import?java.io.*;
          import?javax.servlet.*;
          import?javax.servlet.http.*;

          /**
          ?*用來替代HttpServletReponse的新對(duì)象,以提供緩存能力
          ?
          */

          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請(qǐng)求的內(nèi)容
          ????????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);
          ????????}

          ????}

          ????
          ????
          //判斷是否可以緩存,考慮一個(gè)配置文件配置哪些可以緩存,此處省去
          ????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.實(shí)際應(yīng)用例子:oscache是很好的解決web層緩存的方案!!準(zhǔn)備認(rèn)真讀讀它的源代碼。

          二。資源池模式:
          1。概念:一個(gè)資源池就是一組預(yù)先生成的對(duì)象,它們可以被出借以便節(jié)省多次chuang創(chuàng)建它們所花費(fèi)的時(shí)間。典型的如:EJB池(Service Locator一般都有一個(gè)ejb的home接口池),數(shù)據(jù)庫連接池。

          2。優(yōu)點(diǎn):A。提高了應(yīng)用的可伸縮性,使資源的創(chuàng)建和開銷不至于失控。B,產(chǎn)生了一個(gè)統(tǒng)一的有效微調(diào)點(diǎn),通過運(yùn)行時(shí)修改池參數(shù)來影響應(yīng)用的性能等因素。

          3。簡單實(shí)現(xiàn):
          (1)首先一個(gè)創(chuàng)建對(duì)象的工廠:
          package?pool;

          public?interface?ResourceFactory?{
          ????
          public?Object?createResource();
          ????
          ????
          //驗(yàn)證返回的資源,并提供還原
          ????public?boolean?validateResource(Object?o);
          }


          (2)資源池:

          package?pool;

          import?java.util.*;

          public?class?ResourcePool?{
          ????
          private?ResourceFactory?factory;
          ????
          ???
          //參數(shù)
          ????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)?{}
          ????????}

          ????
          ???????
          //池子已經(jīng)銷毀
          ????????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.實(shí)例:很多開源的數(shù)據(jù)庫連接池,ejb模式中的Service Locator等等
          主站蜘蛛池模板: 奉节县| 浏阳市| 淮滨县| 昆明市| 龙门县| 淳化县| 蛟河市| 郓城县| 绥芬河市| 巴南区| 福泉市| 军事| 邯郸市| 石台县| 龙游县| 乌拉特后旗| 开平市| 珠海市| 赫章县| 云安县| 无为县| 芦溪县| 扬中市| 长子县| 二手房| 东方市| 建德市| 甘谷县| 太仓市| 绥化市| 潞城市| 桂东县| 佛坪县| 尚志市| 丰都县| 胶州市| 景洪市| 叶城县| 玛沁县| 宁德市| 文登市|