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

本文介绍了如何使用Spring AOP结合自定义注解来实现缓存功能。Spring的缓存抽象允许在方法调用时动态传入参数,并利用Spring Expression Language (SpEL)进行表达式计算。从3.1版本开始,Spring引入了注解驱动的缓存技术,无需具体的缓存实现即可轻松实现方法返回结果的缓存。缓存不会自动过期,而是依赖于特定条件触发清除操作。文章还提及了Spring与Ehcache的整合,展示了页面缓存和对象缓存的使用方式。
摘要由CSDN通过智能技术生成

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)和辅助类(ExpressionEvaluator、CacheExpressionRootObject、CacheEvaluationContext、KeyGenerator、MethodCacheKey、SimpleKey、SimpleKeyGenerator、VariableNotAvailableException)代码如下:

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 CacheOperation
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值