oscache对于jsp/servlet的缓存是使用Filter来实现的,对应的类是 com.opensymphony.oscache.web.filter.CacheFilter,既然是Filter那么要看的自然主要有三个方 法:init、doFilter和destroy,这里#destroy()并没有具体实现,只关注前两个即可,首先看一下#init()方法,
public
void
init(FilterConfig filterConfig)
{
config = filterConfig;

log.info( " OSCache: Initializing CacheFilter with filter name " + config.getFilterName());

// 此变量用于防治请求被重复的缓存
requestFiltered = REQUEST_FILTERED + config.getFilterName();
log.info( " Request filter attribute is " + requestFiltered);

// 读取配置文件
Properties props = null ;

try {
// 首先按照Filter参数指定的地方读取配置文件,否则读取默认位置的
String propertiesfile = config.getInitParameter( " oscache-properties-file " );


if (propertiesfile != null && propertiesfile.length() > 0 ) {
props = Config.loadProperties(propertiesfile,
" CacheFilter with filter name ' " + config.getFilterName() + " ' " );
}

} catch (Exception e) {
log.info( " OSCache: Init parameter 'oscache-properties-file' not set, using default. " );
}

// 实例化ServletCacheAdministrator,ServletCacheAdministrator只有一个实例,这里需要关注一下
admin = ServletCacheAdministrator.getInstance(config.getServletContext(), props);

// 缓存超时时间
String timeParam = config.getInitParameter( " time " );

if (timeParam != null ) {

try {
setTime(Integer.parseInt(timeParam));

} catch (NumberFormatException nfe) {
log.error( " OSCache: Unexpected value for the init parameter 'time', defaulting to one hour. Message= "
+ nfe.getMessage());
}
}

// 缓存范围
String scopeParam = config.getInitParameter( " scope " );

if (scopeParam != null ) {

if ( " session " .equalsIgnoreCase(scopeParam)) {
setCacheScope(PageContext.SESSION_SCOPE);

} else if ( " application " .equalsIgnoreCase(scopeParam)) {
setCacheScope(PageContext.APPLICATION_SCOPE);

} else {
log.error( " OSCache: Wrong value ' " + scopeParam
+ " ' for init parameter 'scope', defaulting to 'application'. " );
}

}

// 利用"计划任务"表达式来处理超时时间
setCron(config.getInitParameter( " cron " ));

// 是否处理include
String fragmentParam = config.getInitParameter( " fragment " );

if (fragmentParam != null ) {

if ( " no " .equalsIgnoreCase(fragmentParam)) {
setFragment(FRAGMENT_NO);

} else if ( " yes " .equalsIgnoreCase(fragmentParam)) {
setFragment(FRAGMENT_YES);

} else if ( " auto " .equalsIgnoreCase(fragmentParam)) {
setFragment(FRAGMENT_AUTODETECT);

} else {
log.error( " OSCache: Wrong value ' " + fragmentParam
+ " ' for init parameter 'fragment', defaulting to 'auto detect'. " );
}
}

// 是否处理URL里包括session id的请求
String nocacheParam = config.getInitParameter( " nocache " );

if (nocacheParam != null ) {

if ( " off " .equalsIgnoreCase(nocacheParam)) {
nocache = NOCACHE_OFF;

} else if ( " sessionIdInURL " .equalsIgnoreCase(nocacheParam)) {
nocache = NOCACHE_SESSION_ID_IN_URL;

} else {
log.error( " OSCache: Wrong value ' " + nocacheParam
+ " ' for init parameter 'nocache', defaulting to 'off'. " );
}
}

// 是否处理写入到response中的header属性Last-Modified
String lastModifiedParam = config.getInitParameter( " lastModified " );

if (lastModifiedParam != null ) {

if ( " off " .equalsIgnoreCase(lastModifiedParam)) {
lastModified = LAST_MODIFIED_OFF;

} else if ( " on " .equalsIgnoreCase(lastModifiedParam)) {
lastModified = LAST_MODIFIED_ON;

} else if ( " initial " .equalsIgnoreCase(lastModifiedParam)) {
lastModified = LAST_MODIFIED_INITIAL;

} else {
log.error( " OSCache: Wrong value ' " + lastModifiedParam
+ " ' for init parameter 'lastModified', defaulting to 'initial'. " );
}
}

// 是否处理写入到response中的header属性Expires
String expiresParam = config.getInitParameter( " expires " );

if (expiresParam != null ) {

if ( " off " .equalsIgnoreCase(expiresParam)) {
setExpires(EXPIRES_OFF);

} else if ( " on " .equalsIgnoreCase(expiresParam)) {
setExpires(EXPIRES_ON);

} else if ( " time " .equalsIgnoreCase(expiresParam)) {
setExpires(EXPIRES_TIME);

} else {
log.error( " OSCache: Wrong value ' " + expiresParam
+ " ' for init parameter 'expires', defaulting to 'on'. " );
}
}

// 是否处理写入到response中的header属性Cache-Control
String cacheControlMaxAgeParam = config.getInitParameter( " max-age " );

if (cacheControlMaxAgeParam != null ) {

if (cacheControlMaxAgeParam.equalsIgnoreCase( " no init " )) {
setCacheControlMaxAge(MAX_AGE_NO_INIT);

} else if (cacheControlMaxAgeParam.equalsIgnoreCase( " time " )) {
setCacheControlMaxAge(MAX_AGE_TIME);

} else {

try {
setCacheControlMaxAge(Long.parseLong(cacheControlMaxAgeParam));

} catch (NumberFormatException nfe) {
log.error( " OSCache: Unexpected value for the init parameter 'max-age', defaulting to '60'. Message= "
+ nfe.getMessage());
}
}
}

// ICacheKeyProvider的实例,用于创建缓存的key
ICacheKeyProvider cacheKeyProviderParam = (ICacheKeyProvider) instantiateFromInitParam(
" ICacheKeyProvider " , ICacheKeyProvider. class , this .getClass().getName());

if (cacheKeyProviderParam != null ) {
setCacheKeyProvider(cacheKeyProviderParam);
}

// ICacheGroupsProvider的实例,用于创建缓存的group名字
ICacheGroupsProvider cacheGroupsProviderParam = (ICacheGroupsProvider) instantiateFromInitParam(
" ICacheGroupsProvider " , ICacheGroupsProvider. class , this .getClass().getName());

if (cacheGroupsProviderParam != null ) {
setCacheGroupsProvider(cacheGroupsProviderParam);
}

// EntryRefreshPolicy的实例,用于指定缓存过期策略
EntryRefreshPolicy expiresRefreshPolicyParam = (EntryRefreshPolicy) instantiateFromInitParam(
" EntryRefreshPolicy " , EntryRefreshPolicy. class , ExpiresRefreshPolicy. class .getName());

if (expiresRefreshPolicyParam != null ) {
setExpiresRefreshPolicy(expiresRefreshPolicyParam);

} else {
setExpiresRefreshPolicy( new ExpiresRefreshPolicy(time));
}

// 指定哪些请求方式不去缓存,如GET,POST等
String disableCacheOnMethodsParam = config.getInitParameter( " disableCacheOnMethods " );

if (StringUtil.hasLength(disableCacheOnMethodsParam)) {
disableCacheOnMethods = StringUtil.split(disableCacheOnMethodsParam, ' , ' );
}

}
这个方法主要是对Filter的init-param的载入还有缓存管理器类实例的创建(里面会包括一个Application Scope的Cache的创建还有oscache配置文件的读取)。其中的这句调用时需要关注一下的,admin = ServletCacheAdministrator.getInstance(config.getServletContext(), props),也就是ServletCacheAdministrator类实例的创建。
public
synchronized
static
ServletCacheAdministrator getInstance(ServletContext context, Properties p)
{
// Cache在ServletContext中的属性名
String adminKey = null ;

if (p != null ) {
// 这里是oscache配置文件中的cache.key属性
adminKey = p.getProperty(CACHE_KEY_KEY);
}

if (adminKey == null ) {
adminKey = DEFAULT_CACHE_KEY;
}
// ServletCacheAdministrator在ServletContext中的键值要加上"_admin"这个后缀
adminKey += CACHE_ADMINISTRATOR_KEY_SUFFIX;

// 先尝试在ServletContext中找Cache,当然,第一次初始化时是不会找到的
ServletCacheAdministrator adm