首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

JSP 2.0 動態內容緩存深度解析:EL 表達式驅動的片段級緩存實現

     編輯:關於JSP

傳統 JSP 緩存(如 OSCache、Ehcache 整合)多針對整頁或數據對象,難以滿足「頁面大部分靜態、少量動態個性化」的場景。JSP 2.0 引入的 EL(Expression Language)與標簽庫機制,使得片段級緩存 + 動態表達式運行時求值 成為可能。本文剖析一套基於 SimpleTagSupport 的輕量級緩存標簽庫實現原理。

核心設計:<jc:cache> + <jc:dynamic> 雙標簽協作

<%@ taglib prefix="jc" uri="https://devsphere.com/jspcache" %>

<jc:cache id="productListFragment" scope="application">
  <!-- 這裡的內容只會執行一次,產出的 HTML 存入 application scope -->
  <table>
    <c:forEach items="${productService.latestProducts}" var="p">
      <tr><td>${p.name}</td><td>${p.price}</td></tr>
    </c:forEach>
  </table>
  <!-- 動態插入:當前用戶購物車數量 -->
  <jc:dynamic expr="sessionScope.cart.itemCount" />
</jc:cache>

關鍵類職責

類繼承/實現核心邏輯
CacheTagSimpleTagSupport1. 檢查緩存開關(web.xml init-param)
2. 從指定 scope 獲取緩存字符串,無則執行 body 並捕獲輸出到 StringWriter 存入 scope
3. 調用 JspUtils.eval() 對緩存字符串中的 ${...} 進行 EL 求值
4. 輸出求值結果
DynamicTagSimpleTagSupport1. 構造完整 EL 表達式 ${expr}
2. 向上查找最近的 CacheTag 祖先
3. 若緩存啟用且找到祖先:直接輸出「未求值的表達式字符串」供祖先統一求值
4. 否則:立即調用 JspUtils.eval() 求值並輸出
JspUtils工具類封裝 ExpressionEvaluator,提供 eval(String expr, Class type, JspContext ctx) 統一入口,兼容無 EL 表達式的純文本直通。

EL 求值流程圖解

  1. 首次請求:CacheTag.doTag() → body 執行 → 輸出含 ${sessionScope.cart.itemCount} 的 HTML 字符串 → 存入 application scope。
  2. 後續請求:CacheTag.doTag() → 讀取緩存字符串 → JspUtils.eval() 以當前 PageContext 為上下文求值 → ${sessionScope.cart.itemCount} 解析為當前用戶實際數量 → 輸出最終 HTML。
  3. DynamicTag 僅佔位,不直接輸出值,確保「緩存片段靜態化、動態部分延遲綁定」。

緩存失效策略

  • 手動失效:application.removeAttribute("productListFragment"),配合後台管理「發布商品」操作調用。
  • 定時失效:ScheduledExecutorService 定期清理指定前綴屬性。
  • 版本號機制:ID 中包含版本 productListFragment_v${productVersion},數據變更遞增版本號自動產生新緩存鍵。

優缺點與適用邊界

生產環境建議

小型應用可直接使用此標簽庫;中大型系統建議:

  1. 引入 Spring Cache + Redis 做數據層緩存。
  2. 頁面片段緩存改用 Edge Side Includes (ESI) 或 Nginx fastcgi_cache 卸載到反向代理層。
  3. 若堅持 JSP 層片段緩存,將 CacheTag 存儲後端改為 Redis,ID 帶上租戶/版本維度,實現集群共享與自動過期。

JSP 2.0 EL 驅動的片段緩存,本質是「模板靜態化 + 運行時數據綁定」的輕量級實現。理解其原理有助於在遷移現代模板引擎(Thymeleaf、FreeMarker)時,平滑對接片段緩存策略。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
優點缺點/限制
零依賴,僅需 Servlet/JSP 容器緩存對象為字符串,大片段佔用 Heap,需配合 scope="session" 或外部緩存(Redis)應對大流量
動態表達式靈活,支持任意 EL無內建 LRU/TTL 淘汰,需自行實現或引入成熟框架
開發期可關閉緩存(enabled=false)即時見效集群環境下 application scope 不共享,需改用分佈式緩存 Key