- 浏览: 3358567 次
- 性别:
- 来自: 珠海
文章分类
- 全部博客 (1633)
- Java (250)
- Android&HTML5 (111)
- Struts (10)
- Spring (236)
- Hibernate&MyBatis (115)
- SSH (49)
- jQuery插件收集 (55)
- Javascript (145)
- PHP (77)
- REST&WebService (18)
- BIRT (27)
- .NET (7)
- Database (105)
- 设计模式 (16)
- 自动化和测试 (19)
- Maven&Ant (43)
- 工作流 (36)
- 开源应用 (156)
- 其他 (16)
- 前台&美工 (119)
- 工作积累 (0)
- OS&Docker (83)
- Python&爬虫 (28)
- 工具软件 (157)
- 问题收集 (61)
- OFbiz (6)
- noSQL (12)
最新评论
-
HEZR曾嶸:
你好博主,这个不是很理解,能解释一下嘛//左边+1,上边+1, ...
java 两字符串相似度计算算法 -
天使建站:
写得不错,可以看这里,和这里的这篇文章一起看,有 ...
jquery 遍历对象、数组、集合 -
xue88ming:
很有用,谢谢
@PathVariable映射出现错误: Name for argument type -
jnjeC:
厉害,困扰了我很久
MyBatis排序时使用order by 动态参数时需要注意,用$而不是# -
TopLongMan:
非常好,很实用啊。。
PostgreSQL递归查询实现树状结构查询
缓存方法 : Srping+Ehcache 在Service层配置缓存 http://panyongzheng.iteye.com/blog/2234167
AOP面向切入实现service层嵌入缓存 http://my.oschina.net/vill/blog/550715
使用,在service调用前使用:
转载请声明。
AOP面向切入实现service层嵌入缓存 http://my.oschina.net/vill/blog/550715
//放入缓存注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Inherited public @interface Cacheable { //放入 String key(); //缓存key String fieldKey();// field值 int expireTime() default 3600; } //从缓存中销毁注解 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CacheEvict { //销毁 String key(); String[] fieldKey(); int expireTime() default 3600; } Aspect类 //环绕切入 @Around(value = "@annotation(com.xx.cache.annotation.Cacheable)") public Object cache(ProceedingJoinPoint pjp) { Object result = null; Method method = getMethod(pjp); Cacheable cacheable = method.getAnnotation(Cacheable.class); String fieldKey = cacheable.fieldKey(); if (cacheable.fieldKey().indexOf("#") == 0) {//动态变量存入方式 fieldKey = parseKey(cacheable.fieldKey(), method, pjp.getArgs()); } if (useCache) {//判断是否开启缓存 开启缓存 从缓存获取 result //获取方法的返回类型,让缓存可以返回正确的类型 Class returnType = ((MethodSignature) pjp.getSignature()).getReturnType(); //使用redis 的hash进行存取,易于管理 // result = JedisUtils.hget(cacheable.key(), fieldKey,method.getReturnType()); result = JedisUtils.hget(cacheable.key(), fieldKey, returnType); if (result == null) { try { result = pjp.proceed(); // Assert.notNull(fieldKey); JedisUtils.hset(cacheable.key(), fieldKey, result); logger.debug("The " + cacheable.key() + " add to redis, the fieldKey is " + fieldKey); } catch (Throwable e) { e.printStackTrace(); } } return result; } try { return pjp.proceed(); } catch (Throwable throwable) { throwable.printStackTrace(); return null; } } //环绕切入 @Around(value = "@annotation(com.xx.cache.annotation.CacheEvict)") public Object evict(ProceedingJoinPoint pjp) { //和cache类似,使用Jedis.hdel()删除缓存即可 if (useCache) {//判断是否开启缓存 Method method = getMethod(pjp); CacheEvict cacheEvict = method.getAnnotation(CacheEvict.class); String[] fieldKeys = cacheEvict.fieldKey(); int deleteSuccessFlag = 0; for (String fieldKey : fieldKeys) { if (fieldKey.indexOf("#") == 0) {//动态变量存入方式 String t = fieldKey; fieldKey = parseKey(fieldKey, method, pjp.getArgs()); if (fieldKey == null) { logger.error("cache evict fieldkey {} connot be null, that may be cause data connot sync ", t); t = null; } } deleteSuccessFlag += JedisUtils.hdel(cacheEvict.key(), fieldKey == null ? "" : fieldKey); logger.debug("The reference fieldkey: " + fieldKey + " for " + cacheEvict.key() + " has been delete from redis"); } logger.debug("Delete " + deleteSuccessFlag + " " + cacheEvict.key() + "from redis"); } try { return pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); return null; } } /** * 获取缓存的key * key 定义在注解上,支持SPEL表达式 * * @param key * @param method * @param args * @return */ private String parseKey(String key, Method method, Object[] args) { //获取被拦截方法参数名列表(使用Spring支持类库) LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); String[] paraNameArr = u.getParameterNames(method); //使用SPEL进行key的解析 ExpressionParser parser = new SpelExpressionParser(); //SPEL上下文 StandardEvaluationContext context = new StandardEvaluationContext(); //把方法参数放入SPEL上下文中 for (int i = 0; i < paraNameArr.length; i++) { context.setVariable(paraNameArr[i], args[i]); } return parser.parseExpression(key).getValue(context, String.class); }
使用,在service调用前使用:
@Cacheable(key = "biz_member",fieldKey = "#id") public Member get(String id) { return super.get(id); } @CacheEvict(key = "member",fieldKey = {"#member.id","#member.account"}) public Serializable save(Member member) { return dao.insert(member); } @CacheEvict(key = "member",fieldKey = {"#member.id","#member.account"}) public void delete(Member member) { dao.delete(member); }
转载请声明。
发表评论
-
Spring Boot 属性配置
2016-06-24 11:04 1143Spring Boot 属性配置和使用 http://blog ... -
Spring Boot 集成MyBatis
2016-06-24 10:55 1984Spring Boot 集成MyBatis http://bl ... -
Spring MVC防重复提交
2016-06-17 15:47 1585http://my.oschina.net/zyqjustin ... -
Spring容器加载完之后执行特定任务
2016-06-17 15:36 2236http://my.oschina.net/simpleton ... -
使用spring-session和shiro来代理session的配置
2016-06-16 11:21 11980使用spring-session和redis来代理sessio ... -
JSTL 的 if else : 有 c:if 没有 else 的处理
2016-06-14 09:52 1287http://blog.csdn.net/xiyuan1999 ... -
spring mvc 请求转发和重定向
2016-06-14 09:48 1346http://blog.csdn.net/jackpk/art ... -
mvc:view-controller
2016-05-18 10:26 1044http://blog.csdn.net/lzwglory/a ... -
spring配置事物的方式:注解和aop配置
2016-05-14 00:26 4053参考: Spring AOP中pointcut express ... -
分布式任务调度组件 Uncode-Schedule
2016-05-13 14:47 2234http://www.oschina.net/p/uncode ... -
Mybatis分库分表扩展插件
2016-05-12 15:47 1582http://fangjialong.iteye.com/bl ... -
spring+mybatis+atomikos 实现JTA事务
2016-05-11 22:00 5469sping配置多个数据源 不同用户操作不同数据库 http:/ ... -
Spring中使用注解 @Scheduled执行定时任务
2016-05-10 09:39 1527原文:http://dwf07223.blog.51cto.c ... -
Spring中配置Websocket
2016-05-05 16:55 1237spring+websocket整合(springMVC+sp ... -
redis 集群中Session解决方案之Spring Session
2016-05-04 08:54 1266集群中Session解决方案之Spring Session h ... -
使用Spring-data进行Redis操作
2016-05-04 08:54 4729使用Spring-data进行Redis操作 http://z ... -
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
2016-05-03 13:35 1024Spring4新特性——集成Bean Validation 1 ... -
SpringMVC介绍之Validation
2016-05-03 13:10 948SpringMVC介绍之Validation http://h ... -
spring 注解方式下使用commons-validator 验证表单
2016-05-03 11:08 3031原文: http://www.programgo.com/ar ... -
Spring MVC学习详解
2016-04-28 09:13 960原文 http://blog.csdn.net/alsocod ...
相关推荐
这个也是网上说的面向切面编程AOP。 AOP的概念也很好理解,跟中间件差不多,说白了,就是我可以任意地在方法的前面或后面添加代码,这很适合用于缓存、日志等处理。 在net core2.2时,我当时就尝试过用autofac实现...
Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理Spring AOP面向方面编程原理
spring aop 自定义缓存实现的一个小实例,地址:http://blog.csdn.net/maoyeqiu/article/details/50260357
详细介绍spring aop中9种切入点表达式的写法execute、within、this、target、args、@target、@within、@annotation、@args
一直对AOP面向切面编程的理解很模糊的同学可以看看。
本代码通过使用spring aop+ehcache的技术,实现了方法级别的查询缓存,主要原理是 方法的完整路径+方法参数值,作为key,放入cache中,下次访问时先判断cache中是否有该key.
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop
整理的Spring AOP Aspect切入点语法,老师整理的,2018.08.01最新版
AOP面向切面思想.mp4
Spring-aop面向切面编程实例 日志系统,权限控制等.
aop,面向切面编程
AOP的意思就是面向切面编程。本文主要是通过梳理JDK中自带的反射机制,实现 AOP动态代理模式,这也是Spring AOP 的实现原理
Spring AOP面向方面编程原理:AOP概念,主要介绍面向对象的概念及原理,及作者的一些理解。
一个基于配置文件的Spring AOP的实现。实现了前置通知,后置通知,以及拦截器的功能,配置中有详细的注释。
AOP面向切面编程.ppt
AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程 AOP 面向服务 面向方面编程
AOP面向切面编程实例,可当作业提交。.net代码亲测,完全正确运行。
AOP面向切面编程的JavaScript实现
使用Spring的AOP技术,实现日志记录功能。记录如下信息: 在哪个时间访问了哪个方法,方法传入了哪些参数
AOP 面向方面编程 技术总结 AOP 面向方面编程 技术总结