天天看點

緩存設計方案java緩存的通用實作方案

緩存設計方案

  • java緩存的通用實作方案
    • 設計思路
    • 定義annotation
    • 通過切面掃描标注了@Redis的方法自動實作緩存管理

java緩存的通用實作方案

redis提供的緩存的API,但是在開發階段,如果每個人都自己調用原生API實作緩存時,由于每個人的水準問題,會導緻實作方案千差萬别,同僚又很難統一管理維護

設計思路

通過提供spring的annotation,實作緩存方案的統一

定義annotation

@Target({ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

public @interface Redis {

int expireSeconds() default 0;

boolean isNeedLocalCatch() default false;

}

通過切面掃描标注了@Redis的方法自動實作緩存管理

@Around(“execution(* com.lufax.ztcs….(…)) && @annotation(redis)”)

public Object redis(ProceedingJoinPoint pjp, Redis redis){

Object object = null;

String catchKey = getCatchKey(pjp);

object = getCatchObject(pjp, redis, catchKey);

// "null"為空資料的緩存,防止緩存穿透

if (object != null && “null”.equals(object)) {

return null;

} else if (object != null) {

return object;

}

// 雙重檢查鎖,防止緩存擊穿情況的發送

synchronized(catchKey) {

object = getCatchObject(pjp, redis, catchKey);

if (object != null && “null”.equals(object)) {

return null;

} else if (object != null) {

return object;

}

try {

object = pjp.proceed();

} catch (Throwable throwable) {

Logger.error(this, “方法調用失敗”, throwable);

}

}

int expireSeconds = redis.expireSeconds();

if (expireSeconds == 0) {

// 預設緩存時間是15到20分鐘之間,防止緩存雪崩

expireSeconds = (int)(15+Math.random()(20-15+1));

expireSeconds = expireSeconds 60;

}

putCatchObject(catchKey, redis.expireSeconds(), object, redis.isNeedLocalCatch());

return object;

}

繼續閱讀