标签:缓存 spring annotation aop caching
Spring AOP配置:
<aop:config> <aop:aspect ref="cacheAdvice"> <aop:pointcut id="cachePointcut" expression="execution(* cn.vobile.service..*.*(..)) and @annotation(cacheable)"/> <aop:around method="cacheData" pointcut-ref="cachePointcut"/> </aop:aspect> </aop:config> <bean id="cacheAdvice" class="cn.vobile.common.cache.aop.CacheAdvice"> <property name="cache" ref="localCache"/> </bean>
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface Cacheable {
/**
* The cache key.
*
* @return
*/
String key() default "";
/**
* The cache timeout, unit for minute.
*
* @return
*/
int timeout() default 30;
/**
* Whether serialize the cache object.
*
* @return
*/
boolean serialize() default false;
}public class CacheAdvice extends CacheAdviceSupport {
public Object cacheData(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
Method targetMethod = AopUtils.getMostSpecificMethod(methodSignature.getMethod(), joinPoint.getTarget().getClass());
CacheOperationContext context = getOperationContext(targetMethod, joinPoint.getArgs(), joinPoint.getTarget(), joinPoint.getTarget().getClass());
Object key = generateKey(cacheable, context);
Object cacheObject = getCacheObject(cacheable, key);
if (null != cacheObject) {
return cacheObject;
}
Object result = joinPoint.proceed();
if (null != result) {
cacheObject(cacheable, key, result);
}
return result;
}
private Object getCacheObject(Cacheable cacheable, Object key) {
Object cacheObject = cache.get(key);
if (cacheable.serialize()) {
cacheObject = SerializationUtils.deserialize((byte[]) cacheObject);
}
return cacheObject;
}
private void cacheObject(Cacheable cacheable, Object key, Object value) {
if (cacheable.serialize()) {
value = SerializationUtils.serialize(value);
}
cache.put(key, value, cacheable.timeout());
}
}public abstract class CacheAdviceSupport {
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
private KeyGenerator keyGenerator = new SimpleKeyGenerator();
protected Cache cache;
/**
* Compute the key for the given caching operation.
*
* @return the generated key, or {@code null} if none can be generated
*/
protected Object generateKey(Cacheable cacheable, CacheOperationContext context) {
return context.generateKey(cacheable, ExpressionEvaluator.NO_RESULT);
}
protected CacheOperationContext getOperationContext(Method method, Object[] args, Object target, Class<?> targetClass) {
return new CacheOperationContext(method, args, target, targetClass);
}
protected class CacheOperationContext {
private final Method method;
private final Object[] args;
private final Object target;
private final Class<?> targetClass;
private final MethodCacheKey methodCacheKey;
public CacheOperationContext(Method method, Object[] args, Object target, Class<?> targetClass) {
this.method = method;
this.args = extractArgs(method, args);
this.target = target;
this.targetClass = targetClass;
this.methodCacheKey = new MethodCacheKey(method, targetClass);
}
public Object getTarget() {
return this.target;
}
public Method getMethod() {
return method;
}
public Object[] getArgs() {
return this.args;
}
private Object[] extractArgs(Method method, Object[] args) {
if (!method.isVarArgs()) {
return args;
}
Object[] varArgs = ObjectUtils.toObjectArray(args[args.length - 1]);
Object[] combinedArgs = new Object[args.length - 1 + varArgs.length];
System.arraycopy(args, 0, combinedArgs, 0, args.length - 1);
System.arraycopy(varArgs, 0, combinedArgs, args.length - 1, varArgs.length);
return combinedArgs;
}
/**
* Compute the key for the given caching operation.
*
* @return the generated key, or {@code null} if none can be generated
*/
public Object generateKey(Cacheable cacheable, Object result) {
if (StringUtils.hasText(cacheable.key())) {
EvaluationContext evaluationContext = createEvaluationContext(result);
return evaluator.key(cacheable.key(), this.methodCacheKey, evaluationContext);
}
return keyGenerator.generate(this.target, this.method, this.args);
}
private EvaluationContext createEvaluationContext(Object result) {
return evaluator.createEvaluationContext(Arrays.asList(new Cache[] { cache }), this.method, this.args, this.target, this.targetClass, result);
}
}
/**
* @param keyGenerator the keyGenerator to set
*/
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
/**
* @param cache the cache to set
*/
public void setCache(Cache cache) {
this.cache = cache;
}
}<bean id="trackingListService" class="cn.vobile.service.trackinglist.TrackingListServiceImpl"> <property name="trackingListDao" ref="trackingListDao"></property> </bean>
@Cacheable(key = "'getTrackingListForCompany_'+#companyId+'_'+#orderNumber+'_'+#isContainSubList", timeout = 5, serialize = true)
public List<TrackingList> getTrackingListForCompany(String companyId, int orderNumber, boolean isContainSubList) {
return trackingListDao.getTrackingListForCompany(companyId, orderNumber, isContainSubList );
}标签:缓存 spring annotation aop caching
原文地址:http://blog.csdn.net/thjnemo/article/details/44919463