前言
做web開發(fā)中憔杨,提高系統(tǒng)效率蘸拔,經(jīng)常用到緩存操作。但是代碼中到處都是Cache的操作负芋,為了提高代碼的質(zhì)量漫蛔,在大神的指導(dǎo)下使用面向切面編程,提供一個基于Method的統(tǒng)一的Cache切入功能。
啟用@AspectJ支持
通過在你的Spring的配置中引入下列元素來啟用Spring對@AspectJ的支持:
<aop:aspectj-autoproxy/>
自定義一個Cache注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Cache {
/** * 緩存過期時間莽龟,單位是秒 */
int expire() default 10;
}
完成切面
使用注解來創(chuàng)建切面,around方法獲取緩存值蠕嫁,如果沒有命中到緩存值。應(yīng)該調(diào)用目標(biāo)函數(shù)毯盈,通過目標(biāo)函數(shù)計算實際值剃毒。
@Aspect
@Component
public class CacheIntercepter{
@Around("@annotation(com.spring.aop.annoation.Cache)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
if (joinPoint == null) {
return null;
}
String key = getKey(joinPoint);
CacheClient client = new CacheClient();
String clientValue = client.getValue(key);
if (clientValue != null) {
return clientValue;
}
//如果沒有命中到緩存值。應(yīng)該調(diào)用目標(biāo)函數(shù)搂赋,通過目標(biāo)函數(shù)計算實際值赘阀。
return joinPoint.proceed();
}
/**
* 根據(jù)參數(shù)生成cachekey
* @param joinPoint
* @return
*/
private String getKey(ProceedingJoinPoint joinPoint) {
String result = "";
if (joinPoint.getArgs() == null) {
return result;
}
for (Object key : joinPoint.getArgs()) {
if (key != null) {
result += "_" + key.toString();
}
}
return result;
}
}
緩存客戶端的實現(xiàn)
為簡化起見,假設(shè)key為空值的時候厂镇,緩存值為null纤壁;
public class CacheClient {
public String getValue(String key){
if (key == null || "".equals(key)) {
System.out.println("未命中cache");
} else {
System.out.println("命中cache");
return "success";
}
return null;
}
}
測試用咧
public class CacheTest extends AbstractTest{
@Autowired
private UserService userService;
@Test
public void test(){
{
String cache_result = userService.getId("12");
System.out.println("命中cache的結(jié)果:"+cache_result);
}
{
String uncache_result = userService.getId(null);
System.out.println("未命中cache的結(jié)果:"+uncache_result);
}
}
}
運行結(jié)果
命中cache
命中cache的結(jié)果:success
未命中cache
未命中cache的結(jié)果:我的計算值
第一版的代碼請移步github,注意是feature-aspectj-aop分支。