四大作用域對照表
| 作用域 | scope 值 | 生命週期 | 典型用途 | 對應隱式對象 |
| 頁面 | page | 單次請求處理期間 (含 forward) | 臨時計算、表單回顯 | pageContext |
| 請求 | request | 單次請求 (含 forward/include) | 控制器→視圖傳遞數據 | request |
| 會話 | session | 用戶會話存活期 (瀏覽器關閉/超時失效) | 登入狀態、購物車、偏好設定 | session |
| 應用 | application | Web 應用生命週期 (容器重啟失效) | 全域快取、配置、計數器、線程池 | application |
計數器 Bean CountBean.java
package javabean01;
public class CountBean implements java.io.Serializable {
private int count = 0;
public CountBean() {
System.out.println("====== 新 CountBean 實例誕生 =====");
}
public int getCount() { return ++count; } // 遞增並返回
}
四種作用域驗證頁 counter.jsp
<%@ page contentType="text/html;charset=utf-8" %>
<html><body>
<jsp:useBean id="cou" class="javabean01.CountBean" scope="${param.scope}"/>
<h3>第 <jsp:getProperty name="cou" property="count"/> 次訪問!</h3>
<p>當前 scope: ${param.scope} </p>
<a href="counter.jsp?scope=page">page</a> |
<a href="counter.jsp?scope=request">request</a> |
<a href="counter.jsp?scope=session">session</a> |
<a href="counter.jsp?scope=application">application</a>
</body></html>
預期行為驗證
- page:每次點擊連結 (新請求) 計數器歸 1,控制台每次印「新實例誕生」。
- request:同理,forward 也不共享,每請求新實例。
- session:同瀏覽器多次請求計數遞增;開新瀏覽器/無痕模式 → 新 session → 歸 1。
- application:所有用戶、所有瀏覽器共享同一計數器,重啟 Tomcat 歸零。
作用域選型決策樹
- 數據是否需跨請求保留?否 →
page 或 request (forward 用 request)。
- 是否用戶專屬?是 →
session;否 → application。
application 謹慎使用:併發寫入需同步、記憶體常駐、叢集需外部分布式快取 (Redis)。
現代框架作用域映射
| JSP scope | Spring | CDI (Jakarta EE) |
| page | 無直接對應 (方法區域變數) | 無直接對應 |
| request | @RequestScope | @RequestScoped |
| session | @SessionScope | @SessionScoped |
| application | @ApplicationScope / Singleton | @ApplicationScoped |
避坑指南
- Session 囤積症:大量物件放入 Session 導致記憶體洩漏、序列化失敗。定期
session.removeAttribute()、設定 maxInactiveInterval。
- Application 併發Bug:
count++ 非原子。用 AtomicInteger 或 synchronized 方法。
- 叢集 Session 複製風暴:大 Session 物件跨節點複製延遲大。改用 **Redis Session 共享** (Spring Session)。