spring aop实现注解式缓存
来源:互联网 发布:双色球参选数据真的吗 编辑:程序博客网 时间:2024/06/08 18:21
场景:根据键到缓存中取数据,缓存中没有则从数据库获取,获取后又存进缓存,于是:
private CacheClient cacheClient;
……
public String bindInfo(String organCode, Long userId) {
String cacheKey = ……;
String cacheData = (String) cacheClient.get(cacheKey);
if (cacheData != null) {
return cacheData;
} else {
……
String data = sessionTemplate.selectOne(……, ……);
if (data != null) {
cacheClient.set(cacheKey, data);
}
return data;
}
}
上述代码很常见,写到烦。
懒人懒招:
1、自定义缓存与清除缓存注解
2、mvel合成cacheKey
一、缓存注解与aop
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface CacheConfig {
String template() default "";//缓存键值模板
String[] expression() default {};//获取缓存键值表达式
int expires() default -1;//过期时间
}
@Component
@Aspect
public class CacheConfigAspect {
private static final Logger logger = LoggerFactory.getLogger(CacheConfigAspect.class);
@Autowired
private CacheClient cacheClient;
private static CacheMap<String, Class> returnTypeCache = new LFUCache<String, Class>(1000, 2 * 60 * 1000);
@Pointcut(value = "@annotation(com.yiwuliu.cache.annotations.CacheConfig) && @annotation(cacheConfig)")
public void cacheConfigAspect(CacheConfig cacheConfig) {
}
@Around(value = "cacheConfigAspect(cacheConfig)")
public Object needCacheAround(ProceedingJoinPoint joinPoint, CacheConfig cacheConfig) {
Object data = null;
try {
String template = cacheConfig.template();
String[] expressions = cacheConfig.expression();
Object[] params = joinPoint.getArgs();
String cacheKey = AssembleUtil.assembleCacheKey(template, expressions, params);
Class clazz = returnTypeCache.get(joinPoint.toLongString());
if (!Strings.isNullOrEmpty(cacheKey) && null != clazz) {
data = getDataFromCache(clazz, cacheKey);
}
if (null == data) {
data = getDataFromDB(joinPoint, cacheConfig, cacheKey);
}
} catch (Throwable e) {
logger.error("{} failed to get info from cache in result of {}", joinPoint.getSignature().toLongString(),
e.toString());
}
return data;
}
}
二、缓存清除注解与aop
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Documented
public @interface CacheClear {
String template() default "";//缓存键值模板
String[] expressions() default {};//获取缓存键值表达式
}
@Component
@Aspect
public class CacheClearAspect {
private static final Logger logger = LoggerFactory.getLogger(CacheClearAspect.class);
@Autowired
private CacheClient cacheClient;
@Pointcut(value = "@annotation(com.yiwuliu.cache.annotations.CacheClear) && @annotation(cacheClear)")
public void cacheClearAspect(CacheClear cacheClear) {
}
@Around(value = "cacheClearAspect(cacheClear)")
public Object clearAspect(ProceedingJoinPoint joinPoint, CacheClear cacheClear) {
Object result = null;
try {
String template = cacheClear.template();
String[] expressions = cacheClear.expressions();
Object[] params = joinPoint.getArgs();
result = joinPoint.proceed(params);
String cacheKey = AssembleUtil.assembleCacheKey(template, expressions, params);
cacheClient.delete(cacheKey);
logger.debug("CacheClearsAspect Remove From Cache : {}", cacheKey);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return result;
}
}
三、AssembleUtil合成CacheKey
public final class AssembleUtil {
private static final String SEPARATOR = ":";
public static List<String> assembleCacheKeys(String[] templates, String[] expressions,
Object[] params) throws Exception {
List<java.lang.String> cacheKeys = Lists.newArrayList();
expressions = templateValues(expressions, params);
for (java.lang.String template : templates) {
cacheKeys.add(MessageFormat.format(template, expressions));
}
return cacheKeys;
}
public static String assembleCacheKey(String template, String[] expressions, Object[] params) throws Exception {
return MessageFormat.format(template, templateValues(expressions, params));
}
private static String[] templateValues(String[] expressions, Object[] params) {
for (int i = 0; i < expressions.length; i++) {
java.lang.String[] split = expressions[i].split(SEPARATOR);
int argsIndex = Integer.parseInt(split[0]) - 1;
if (split.length == 1) {
expressions[i] = java.lang.String.valueOf(params[argsIndex]);
} else {
expressions[i] = java.lang.String.valueOf(MVEL.eval(split[1], params[argsIndex]));
}
}
return expressions;
}
}
四、怎么用???
1、spring文件中加入aop:aspect-autoproxy配置,依赖org.aspectj:aspectjweaver、org.aspectj:aspectjrt
<aop:aspectj-autoproxy expose-proxy="true"/>
2、给需要缓存结果的方法加注解
@CacheConfig(template = "phone:bind:{0}:{1}", expression = {"1", "2"})
public OpenUserModel bindInfo(String organCode, Long userId) {
Map<String, Object> params = Maps.newHashMap();
params.put(ParamsKey.ORGAN_CODE, organCode);
params.put(ParamsKey.USER_ID, userId);
return sessionTemplate.selectOne("phone.bind.bindInfo", params);
}
3、给需要清除缓存的方法加注解
@CacheClear(template = "phone:bind:{0}:{1}", expressions = {"1:organCode", "1:userId"})
public void bind(OpenUserModel openUserModel) {
sessionTemplate.insert(……, ……);
}
纯粹小白,欢迎路过大神指正!
0 0
- spring aop实现注解式缓存
- Spring AOP+自定义注解实现缓存
- spring(AOP) 注解实现aop
- Spring AOP+注解的方式实现缓存的获取
- spring注解实现AOP
- Spring注解实现AOP
- Spring 注解Aop实现
- 【spring】AOP注解实现
- spring 注解实现AOP
- Spring AOP 注解实现
- 使用注解实现Spring aop
- 十、Spring AOP注解实现
- Spring 注解实现AOP通知
- spring使用注解实现AOP
- spring注解形式aop实现
- Spring-注解方式实现AOP
- Spring的AOP注解实现
- 基于注解spring AOP实现
- 关于大型网站技术演进的思考(一)--存储的瓶颈(1)
- 【Android】通用系列 —— 下拉刷新之继承ListView的下拉刷新
- 自动引入包存在的一些异常:引入不对应同名类
- 标准化欧式距离
- 如何清理arp缓存和清除dns缓存
- spring aop实现注解式缓存
- 发布前后版本数值变化
- SSZipArchive的使用详解和遇到的问题
- JavaScript基础内容复习1
- HDOJ 1018 Big Number
- mysql 查询当天当周当月的数据
- 文章标题
- Java 代码编译和执行的整个过程详解
- shell教程六:多行输入 、调试