Spring AOP+自定义注解实现缓存

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>自定义注解Cacheable代码如下:

@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;}切面处理类(CacheAdvice)及其父类(CacheAdviceSupport)代码如下:

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 KeyGeneratorkeyGenerator = new SimpleKeyGenerator();protected Cachecache;/*** 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 Methodmethod;private final Object[]args;private final Objecttarget;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>TrackingListServiceImpl类里面进行缓存的方法:

不甚酒力,体会不了酒的美味,但却能感受知已的妙处。

Spring AOP+自定义注解实现缓存

相关文章:

你感兴趣的文章:

标签云: