当前位置: 首页 > 工具软件 > ecache > 使用案例 >

ecache和redis缓存

宦琪
2023-12-01

最近在写自己框架的时候研究了下ecache缓存技术,我在纠结使用ecache还是使用redis呢,因为redis是基于内存的缓存技术,当然他们的应用场景不同。我更加倾向于redis,所以,自己写了基于spring aop的redis注解,本来想用ecache的注解方式实现redis注解,发现工作量庞大,所以,就实现了一个最初版:
注解
package com.nise.common.framework.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 缓存切面
*
*
* @author gerry
* @version 1.0, 2016年1月12日下午5:40:02
* @since com.gerry.link 1.0
* @see com.nise.common.framework.redis.RequireCacheInterceptor
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface RequireCache {

String value();

String key() default "";

/**
 * 设置秒,默认5分钟
 *  
 * @return
 * @see
 */
int seconds() default 300;

}

package com.nise.common.framework.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 删除缓存
*
*
* @author gerry
* @version 1.0, 2016年1月13日上午9:35:18
* @since com.gerry.link 1.0
* @see com.nise.common.framework.redis.DeleteCacheInterceptor
*/
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DeleteCache {

String value();

String key() default "";

}

package com.nise.common.framework.redis;

import java.lang.reflect.Method;

import lombok.extern.slf4j.Slf4j;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.nise.common.framework.annotations.RequireCache;
import com.nise.common.framework.constants.CommonConstants;
import com.nise.common.framework.utils.EmptyUtils;

/**
* 缓存注解
*
*
* @author gerry
* @version 1.0, 2016年1月12日下午5:44:39
* @since com.gerry.link 1.0
*/
@Slf4j
public class RequireCacheInterceptor implements MethodInterceptor {

@Autowired
private RedisManager<String, Object> redis;

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    RequireCache cache = method.getAnnotation(RequireCache.class);
    if (EmptyUtils.isEmpty(cache)) {// 不需要缓存
        return invocation.proceed();
    }
    Object[] params = invocation.getArguments();
    // key的规则就是:当前执行类的名字+"_"+方法名字+"_"+value+"_"+key+key的值
    StringBuffer sb = new StringBuffer(cache.value()).append(CommonConstants.SYMBOL_UNDERLINE).append(invocation.getThis().getClass().getName()).append(CommonConstants.SYMBOL_UNDERLINE)
            .append(method.getName());
    if (EmptyUtils.isNotEmpty(cache.key()) && StringUtils.startsWith(cache.key(), CommonConstants.SYMBOL_DELIMITER)) {
        sb.append(CommonConstants.SYMBOL_UNDERLINE).append(params[0]).append(CommonConstants.SYMBOL_UNDERLINE).append(cache.key());
    }

    Object obj = redis.getObjectByKey(sb.toString());// 先从redis中找,如果有,则直接返回,否则查询保存redis
    if (EmptyUtils.isNotEmpty(obj)) {
        log.info("根据key[" + sb.toString() + "]从缓存中获取数据");
        return obj;
    }
    obj = invocation.proceed();
    if (EmptyUtils.isNotEmpty(obj)) {
        log.info("根据key[" + sb.toString() + "]把数据放入缓存");
        redis.saveObjectBySeconds(sb.toString(), obj, cache.seconds());
    }

    return obj;
}

}

package com.nise.common.framework.redis;

import java.lang.reflect.Method;

import lombok.extern.slf4j.Slf4j;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.nise.common.framework.annotations.DeleteCache;
import com.nise.common.framework.constants.CommonConstants;
import com.nise.common.framework.utils.EmptyUtils;

/**
* 缓存注解
*
*
* @author gerry
* @version 1.0, 2016年1月12日下午5:44:39
* @since com.gerry.link 1.0
*/
@Slf4j
public class DeleteCacheInterceptor implements MethodInterceptor {

@Autowired
private RedisManager<String, Object> redis;

@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
    Method method = invocation.getMethod();
    DeleteCache cache = method.getAnnotation(DeleteCache.class);
    if (EmptyUtils.isNotEmpty(cache)) {
        Object[] params = invocation.getArguments();
        StringBuffer sb = new StringBuffer(cache.value()).append(CommonConstants.SYMBOL_UNDERLINE).append(invocation.getThis().getClass().getName()).append(CommonConstants.SYMBOL_UNDERLINE)
                .append(method.getName());
        if (EmptyUtils.isNotEmpty(cache.key()) && StringUtils.startsWith(cache.key(), CommonConstants.SYMBOL_DELIMITER)) {
            sb.append(CommonConstants.SYMBOL_UNDERLINE).append(params[0]).append(CommonConstants.SYMBOL_UNDERLINE).append(cache.key());
        }
        redis.deleteObjectByKey(sb.toString());
        log.info("根据key[" + sb.toString() + "]删除缓存数据");
    }
    return invocation.proceed();
}

}

spring配置

<bean id="deleteCacheInterceptor" class="com.nise.common.framework.redis.DeleteCacheInterceptor">
</bean>

<aop:config>
    <!--切入点 -->
    <aop:pointcut id="lockPointcut" expression="execution(* com.gerry.common.*.service.impl.*.*(..))" />
    <!--在该切入点使用自定义拦截器 -->
    <aop:advisor pointcut-ref="lockPointcut" advice-ref="requireCacheInterceptor" order="1" />
</aop:config>

<aop:config>
    <!--切入点 -->
    <aop:pointcut id="lockPointcut" expression="execution(* com.gerry.common.*.service.impl.*.*(..))" />
    <!--在该切入点使用自定义拦截器 -->
    <aop:advisor pointcut-ref="lockPointcut" advice-ref="deleteCacheInterceptor" order="2" />
</aop:config>

当然这里的RedisManager也是我自己实现的。
希望有想法的有志青年,可以和我一起实现redis缓存注解功能,目前我这个只是雏形,当然了,这个雏形已经可以进行业务应用了。

 类似资料: