在上篇博客中,介紹了如何借助Spring Module項(xiàng)目,配置聲明式緩存功能實(shí)現(xiàn),文中只針對(duì)Ehcahce的實(shí)現(xiàn)進(jìn)行了講解,其實(shí)Spring Module項(xiàng)目把這塊的功能做了一個(gè)很好的抽取,使其能更方便的對(duì)其它的緩存框架的支持和擴(kuò)展。筆者正好利用該代碼框架實(shí)現(xiàn)了與Memcached服務(wù)的集成,本文將得點(diǎn)通過(guò)源代碼解講一下抽取這層的實(shí)現(xiàn),希望對(duì)大家有所幫助。注:本文只講緩存部分的實(shí)現(xiàn),刷新部分功能相同,請(qǐng)大家自己源讀代碼即可。
先看一下Spring的配置內(nèi)容
1 <!-- 緩存攔截器 -->
2 <bean id="cachingInterceptor"
3 class="org.springmodules.cache.interceptor.caching.MethodMapCachingInterceptor">
4 <property name="cacheProviderFacade" ref="cacheProviderFacade" />
5 <property name="cachingModels"> <!-- 進(jìn)行cache緩存 -->
6 <props> <!-- 所有StudentService對(duì)象中,以get開(kāi)頭的方法都將進(jìn)行緩存 -->
7 <prop key="StudentService.get*">cacheName=testCache</prop>
8 </props>
9 </property>
10 </bean>
11
12
13 <!-- 配置 基于BeanName規(guī)則的動(dòng)態(tài)代理封裝 -->
14 <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
15 <property name="beanNames">
16 <list>
17 <value>studentService</value>
18 </list>
19 </property>
20 <property name="interceptorNames">
21 <list>
22 <value>cachingInterceptor</value>
23 <value>flushingInterceptor</value>
24 </list>
25 </property>
26 </bean>
通過(guò)Spring提供的BeanNameAutoProxyCreator類,提供對(duì)Bean對(duì)象的統(tǒng)一自動(dòng)代理實(shí)現(xiàn)。從上面的配置中,實(shí)現(xiàn)緩存攔截的實(shí)現(xiàn)類就是org.springmodules.cache.interceptor.caching.MethodMapCachingInterceptor。實(shí)現(xiàn)了MethodInterceptor接口,對(duì)代理的對(duì)象的方法調(diào)用進(jìn)行攔截,實(shí)現(xiàn)緩存功能。2 <bean id="cachingInterceptor"
3 class="org.springmodules.cache.interceptor.caching.MethodMapCachingInterceptor">
4 <property name="cacheProviderFacade" ref="cacheProviderFacade" />
5 <property name="cachingModels"> <!-- 進(jìn)行cache緩存 -->
6 <props> <!-- 所有StudentService對(duì)象中,以get開(kāi)頭的方法都將進(jìn)行緩存 -->
7 <prop key="StudentService.get*">cacheName=testCache</prop>
8 </props>
9 </property>
10 </bean>
11
12
13 <!-- 配置 基于BeanName規(guī)則的動(dòng)態(tài)代理封裝 -->
14 <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
15 <property name="beanNames">
16 <list>
17 <value>studentService</value>
18 </list>
19 </property>
20 <property name="interceptorNames">
21 <list>
22 <value>cachingInterceptor</value>
23 <value>flushingInterceptor</value>
24 </list>
25 </property>
26 </bean>
下面是完整的類圖:

從類圖中,可以看到AbstractCachingInterceptor抽象實(shí)現(xiàn)了MethodInterceptor接口的invoke方法。這也是整個(gè)緩存處理的入口。
看代碼之前,我先來(lái)補(bǔ)充一下框架是如果實(shí)現(xiàn)方法攔截后的匹配過(guò)程。
首先是構(gòu)建匹配規(guī)則:
由 MethodMapCachingInterceptor類的onAfterPropertiesSet方法實(shí)現(xiàn)。
實(shí)現(xiàn)思路如下:
取得 cachingModels屬性,遍歷每一個(gè) key
例如上例中 StudentService.get* , 解析出 class 類名(StudentService),和方法的匹配字符串(get*)
然后通過(guò) Class.forName 方法,裝載該類,取出該類的所有方法,一一與指定的方法匹配字符串進(jìn)行 正則匹配TextMatcher.isMatch,匹配通過(guò)的則放入到一個(gè)Map中, key=Method對(duì)象, value=CacheModel對(duì)象當(dāng) 攔截器 對(duì)調(diào)用的方法進(jìn)行攔截時(shí),通過(guò) map.get返回值來(lái)確認(rèn)是否對(duì)方法進(jìn)行緩存處理
實(shí)現(xiàn)代碼如下:已經(jīng)添加注釋
1 public final Object invoke(MethodInvocation mi) throws Throwable {
2 Method method = mi.getMethod();//取得攔截的方法
3 if (!CachingUtils.isCacheable(method))
4 return methodNotCacheable(mi, method); //如果是void返回值,則不需要緩存支持
5
6 CachingModel model = model(mi); //根據(jù)method,則定是否要進(jìn)行緩存
7 if (model == null) return noModelFound(mi, method);
8
9 Serializable key = keyGenerator.generateKey(mi);//根據(jù)方法對(duì)象,生成key
10 Object cached = cache.getFromCache(key, model);//如果有緩存
11
12 if (null == cached) return cachedValueFromSource(mi, key, model); //如果沒(méi)有緩存,把返回保存到緩存
13 return unmaskNull(cached);
14 }
2 Method method = mi.getMethod();//取得攔截的方法
3 if (!CachingUtils.isCacheable(method))
4 return methodNotCacheable(mi, method); //如果是void返回值,則不需要緩存支持
5
6 CachingModel model = model(mi); //根據(jù)method,則定是否要進(jìn)行緩存
7 if (model == null) return noModelFound(mi, method);
8
9 Serializable key = keyGenerator.generateKey(mi);//根據(jù)方法對(duì)象,生成key
10 Object cached = cache.getFromCache(key, model);//如果有緩存
11
12 if (null == cached) return cachedValueFromSource(mi, key, model); //如果沒(méi)有緩存,把返回保存到緩存
13 return unmaskNull(cached);
14 }
到些基本的實(shí)現(xiàn)流程已經(jīng)講解完了,其它的大家可以通過(guò)閱讀源代碼進(jìn)行理解。
最后補(bǔ)充一下如何根據(jù)這個(gè)框架集成其它的緩存服務(wù),需要實(shí)現(xiàn)的接口和繼承的抽象類如下:
AbstractCacheProviderFacade 緩存保存,取得,更新的實(shí)現(xiàn)
AbstractCacheModelValidator 檢測(cè)緩存模型合法性
CachingModel 保存緩存的模型接口
AbstractFlushingModel 刷新緩存的模型抽象類
Good Luck!
Yours Matthew!
posted on 2010-05-13 19:53 x.matthew 閱讀(4460) 評(píng)論(2) 編輯 收藏 所屬分類: Spring|Hibernate|Other framework