OSCache - CacheFilter工作原理

[color=darkblue][b]系統啓動 – CacheFilter[/b][/color]
OSCache頁面緩存在使用時需要在web.xml中配置CacheFilter,在容器中,Filter先於Servlet啓動,下面看看CacheFilter在容器啓動時,做了哪些工作:
首先需要了解OSCache的幾個類:
[color=indigo]ServletCacheAdministrator[/color] -- 該類用於創建、刷新、管理緩存。
[color=indigo]Config[/color] -- 負責獲取緩存配置文件,即oscache.properties。如果使用默認的構造函數,這個類會從properties文件中加載緩存配置。
[color=indigo]Cache[/color] -- 爲緩存本身提供一個接口。這個類的實例會根據它的構造參數創建一個緩存。

/** 初始化Filter
* 獲取web.xml文件的配置,創建ServletCacheAdministrator對象
* 獲取web.xml文件中CacheFilter的初始化配置 */
public void init(FilterConfig filterConfig) {
config = filterConfig;
//初始化了ServletCacheAdministrator對象
admin = ServletCacheAdministrator.getInstance(config.getServletContext());
try {
time = Integer.parseInt(config.getInitParameter("time"));
} catch (Exception e) {
log.info("Could not get init paramter 'time', defaulting to one hour.");
}
try {
String scopeString = config.getInitParameter("scope");
if (scopeString.equals("session")) {
cacheScope = PageContext.SESSION_SCOPE;
} else if (scopeString.equals("application")) {
cacheScope = PageContext.APPLICATION_SCOPE;
} else if (scopeString.equals("request")) {
cacheScope = PageContext.REQUEST_SCOPE;
} else if (scopeString.equals("page")) {
cacheScope = PageContext.PAGE_SCOPE;
}
} catch (Exception e) {
log.info("Could not get init paramter 'scope', defaulting to 'application'");
}
}


從以上可以看出,OSCache隨系統啓動,僅僅做了三個步驟:
1. 創建了一個ServletCacheAdministrator對象;
2. 獲取web.xml配置文件中刷新時間
3. 獲取web.xml配置文件中刷新範圍
在創建ServletCacheAdministrator對象時,OSCache進行了如下工作:

public static ServletCacheAdministrator getInstance(ServletContext context) {
return getInstance(context, null);
}
public static ServletCacheAdministrator getInstance(ServletContext context, Properties p) {
ServletCacheAdministrator admin = null;
admin = (ServletCacheAdministrator) context.getAttribute(CACHE_ADMINISTRATOR_KEY);
//檢測Web Application中是否包含名爲__oscache_admin的屬性,啓動時不包含,故admin爲null
if (admin == null) {
admin = new ServletCacheAdministrator(context, p); //調用私有化構造函數
context.setAttribute(CACHE_ADMINISTRATOR_KEY, admin); //將admin加入__oscache_admin屬性
if (log.isInfoEnabled()) {
log.info("Created new instance of ServletCacheAdministrator");
}
admin.getAppScopeCache(context);
//獲取application範圍緩存的方法,在這個方法中,創建並初始化了Cache和Config對象
}
return admin;
}


ServletCacheAdministrator的構造函數:

private ServletCacheAdministrator(ServletContext context, Properties p) {
super(p);
/* 父類方法做了如下工作:
* 從classpath下讀取OSCache屬性文件
* 通過屬性文件的配置初始化緩存參數 */
config.set(HASH_KEY_CONTEXT_TMPDIR,
context.getAttribute("javax.servlet.context.tempdir"));
//設置context.tempdir = D:\Tomcat6\work\Catalina\localhost\OSCacheWebTest
flushTimes = new HashMap();
initHostDomainInKey(); //私有變量boolean useHostDomainInKey = null
}

通過以上方法,在ServletContext上下文中,設置瞭如下屬性:
context.setAttribute(CACHE_ADMINISTRATOR_KEY, admin);
將創建的ServletCacheAdministrator對象放入名爲__oscache_admin的屬性
context.setAttribute(getCacheKey(), cache);
將創建的Cache對象放入名爲__oscache_cache的屬性

[b][color=darkblue]緩存頁面首次打開與刷新 – doFilter[/color][/b]
首先需要了解OSCache的幾個類:
ResponseContent:在緩存中用byte數組形式保留servlet響應對象。

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws ServletException, IOException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
//產生一個緩存目錄的key:/OSCacheWebTest/cache1.jsp_GET_
String key = admin.generateEntryKey(null, httpRequest, cacheScope);
//獲取指定範圍的緩存
Cache cache = admin.getCache(httpRequest, cacheScope);
以上語句進行了如下工作:
1. 定位緩存範圍:session還是application(這裏在配置文件中設置的是session)
2. 檢查HttpSession對象中名爲__oscache_cache的屬性是否爲空
如果爲空(第一次打開頁面):創建一個緩存,將其放入HttpSession對象的__oscache_cache屬性中
不爲空(刷新頁面):直接從HttpSession對象中獲取__oscache_cache屬性的值,即直接獲取緩存
try {
//通過緩存中的key得到相應的對象
ResponseContent respContent = (ResponseContent) cache.getFromCache(key, time);
respContent.writeTo(response); //將緩存數據寫入到ServletResponse
} catch (NeedsRefreshException nre) {
………………
} finally {
………………
}
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章