- 浏览: 123294 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
wellba:
完美的解决了问题,谢谢分享
Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): -
u013641752:
添加上去了,但是结果好像一样的,也是删除不了呢。而且是只有删除 ...
Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL): -
zl584521:
NAMES.DIRECTORY_PATH= (TNSNAMES ...
PLSQL连接ORACLE详解 -
hezonghuan:
谢了!
Eclipse 中Tomcat 启动报错:java.net.SocketException: select failed -
zhonglijunyi:
学习中,但是PL/SQL连接碰到很多问题啊
PLSQL连接ORACLE详解
首页发现篇,虽然跟我的不一样,但思路大致相同,大家可以参考下咯
http://mixer-b.iteye.com/blog/1563872
以前没具体做过缓存,于是上网搜了下资料,于是得知spring+ehcache做缓存一些考虑因素:
1、缓存的切面放在哪一层最合适(大部分情况是service,dao),其实应用在哪一层都有各自的用武之地,如:
一、放在service,是缓存整个经过业务处理后的一个结果,这样的做法大大减少了系统逻辑处理,但如果业务方法里面涉及到多表操作,则比较麻烦,因为要考虑缓存数据更新的问题。
二、放在dao,大多数都放在这层,也是推荐放在这层,因为基本不用人为的考虑缓存及时更新的问题造成业务方法返回的结果不一致。只缓存数据,不牵扯到业务逻辑
2、对于某些特殊情况下的方法,不需要缓存,或者不需要更新缓存的方法,通过参数排除
3、考虑需要缓存更新,所以需要两个拦截器去拦截不同的方法,做不同的处理
一、缓存拦截器,在方法调用之前拦截,如(find,query,select,get方法),经过一些逻辑处理,再判断返回缓存还是真实的数据
二、更新缓存拦截器,在方法调用之后,如(save,insert,update,delete方法)
于是马上动手:
缓存拦截器 MethodCacheInterceptor
更新缓存拦截器,MethodCacheAfterAdvice
spring 配置文件
ehcache缓存配置文件:ehcache.xml
http://mixer-b.iteye.com/blog/1563872
以前没具体做过缓存,于是上网搜了下资料,于是得知spring+ehcache做缓存一些考虑因素:
1、缓存的切面放在哪一层最合适(大部分情况是service,dao),其实应用在哪一层都有各自的用武之地,如:
一、放在service,是缓存整个经过业务处理后的一个结果,这样的做法大大减少了系统逻辑处理,但如果业务方法里面涉及到多表操作,则比较麻烦,因为要考虑缓存数据更新的问题。
二、放在dao,大多数都放在这层,也是推荐放在这层,因为基本不用人为的考虑缓存及时更新的问题造成业务方法返回的结果不一致。只缓存数据,不牵扯到业务逻辑
2、对于某些特殊情况下的方法,不需要缓存,或者不需要更新缓存的方法,通过参数排除
3、考虑需要缓存更新,所以需要两个拦截器去拦截不同的方法,做不同的处理
一、缓存拦截器,在方法调用之前拦截,如(find,query,select,get方法),经过一些逻辑处理,再判断返回缓存还是真实的数据
二、更新缓存拦截器,在方法调用之后,如(save,insert,update,delete方法)
于是马上动手:
缓存拦截器 MethodCacheInterceptor
package com.eclink.cache; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.NotSerializableException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.Set; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.log4j.Logger; import org.junit.Assert; import org.springframework.beans.factory.InitializingBean; import com.eclink.common.Common; public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean { private static final Logger log = Logger.getLogger(MethodCacheInterceptor.class); private Cache cache; private List<String> noCacheMethod; public void setNoCacheMethod(List<String> noCacheMethod) { this.noCacheMethod = noCacheMethod; } public void setCache(Cache cache) { this.cache = cache; } /** * 拦截service/dao中的方法,如果存在该结果,则返回cache中的值。<br> * 否则,则从数据库中查询返回并放入cache中 * @throws Throwable */ public Object invoke(MethodInvocation invocation) throws Throwable { String targetName = invocation.getThis().getClass().getName(); String methodName = invocation.getMethod().getName(); Object[] args = invocation.getArguments(); Object result = null; // 排除不需要缓存的方法 boolean noCache = false; if(!Common.isEmpty(noCacheMethod)){ String s = targetName +"."+methodName; for (String method : noCacheMethod) { if(s.indexOf(method) != -1){ noCache = true; break; } } } if(noCache){ // 不需要缓存,直接调用方法返回值 return invocation.proceed(); } else{ String cacheKey = getCacheKey(targetName, methodName, args); log.debug("find object from "+cache.getName()+" : "+cacheKey); Element e = cache.get(cacheKey); if(e == null){ log.debug("can't find object in "+cache.getName()+", get method result and create the cache(key: "+cacheKey+")."); result = invocation.proceed(); if(result == null)return null; if(!(result instanceof Serializable)){ // 如果返回结果不可序列化,则不缓存,直接返回 log.info(result + " is not Serializable,Can't use cache."); return result; } e = new Element(cacheKey, result); cache.put(e); } // 返回克隆的对象,这个看需求了,如果你想直接修改缓存里对象的值,就直接返回缓存里的对象 return cloneObject(e.getValue()); } } /** * 克隆对象 * @param obj * @return */ private Object cloneObject(Object obj){ ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; try { bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(obj); bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); return ois.readObject(); }catch(NotSerializableException e1){ log.warn(obj+" can't be clone"); e1.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }finally{ try { if(ois != null) ois.close(); if(bis != null) bis.close(); if(oos != null) oos.close(); if(bos != null) bos.close(); } catch (IOException e) { e.printStackTrace(); } } return obj; } /** * 构建缓存的key。 * 获得cacheKey的方法. key为:包名.类名.方法名 如:com.eclink.service.buscert.BusCertService.getBusCertList * @param targetName 类名 * @param methodName 方法名 * @param args 参数 * @return String */ private String getCacheKey(String targetName, String methodName, Object[] args){ StringBuilder sb = new StringBuilder(); sb.append(targetName).append(".").append(methodName); if(!Common.isEmpty(args)){ for (Object arg : args) { // 这里将参数克隆,防止直接修改传入的对象参数。 // TODO 只判断了简单的map,和object[]这种特殊情况,具体情况视项目情况再完善 Object o = cloneObject(arg); if(o instanceof Map){ Map mapo = (Map)o; Set<String> keys = mapo.keySet(); for (String key : keys) { Object keyValue = mapo.get(key); if(keyValue instanceof Object[]){ mapo.put(key, convertObjectArray((Object[])keyValue)); } } } if (o instanceof Object[]) { sb.append(".").append(convertObjectArray((Object[])o)); }else{ sb.append(".").append(o); } } } return sb.toString(); } /** * 将数组原始的toString()方法,转换成字符串 * @param objs * @return */ public String convertObjectArray(Object[] objs){ StringBuilder sb = new StringBuilder(); sb.append("["); for (Object obj : objs) { sb.append(obj).append(","); } sb.append("]"); return sb.toString(); } public void afterPropertiesSet() throws Exception { Assert.assertNotNull("Need a cache,pleace use setCache(cache) create it.", cache); } }
更新缓存拦截器,MethodCacheAfterAdvice
package com.eclink.cache; import java.lang.reflect.Method; import java.util.List; import net.sf.ehcache.Cache; import org.apache.log4j.Logger; import org.junit.Assert; import org.springframework.aop.AfterReturningAdvice; import org.springframework.beans.factory.InitializingBean; import com.eclink.common.Common; public class MethodCacheAfterAdvice implements AfterReturningAdvice, InitializingBean { private static final Logger log = Logger.getLogger(MethodCacheAfterAdvice.class); private Cache cache; private List<String> noFlushCacheMethod; public void setNoFlushCacheMethod(List<String> noFlushCacheMethod) { this.noFlushCacheMethod = noFlushCacheMethod; } public void setCache(Cache cache) { this.cache = cache; } /** * 刷新缓存(在目标方法执行之后,执行该方法) */ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { String className = target.getClass().getName(); String methodName = method.getName(); // 排除不需要刷新缓存的方法 boolean noFlushCache = false; if(!Common.isEmpty(noFlushCacheMethod)){ String s = className +"."+methodName; for (String m : noFlushCacheMethod) { if(s.indexOf(m) != -1){ noFlushCache = true; break; } } } if(!noFlushCache){ List<String> cacheKeys = cache.getKeys(); for (String cacheKey : cacheKeys) { if(cacheKey.startsWith(className)){ cache.remove(cacheKey); log.debug("remove cache "+cacheKey); } } } } public void afterPropertiesSet() throws Exception { Assert.assertNotNull("Need a cache,pleace use setCache(cache) create it.", cache); } }
spring 配置文件
<bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation"> <value>classpath:ehcache.xml</value> </property> </bean> <!-- defind cache factory and set cacheName --> <bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="defaultCacheManager" /> <property name="cacheName"> <value>FDOL2_CACHE</value> </property> </bean> <!-- find/create cache --> <bean id="methodCacheInterceptor" class="com.eclink.cache.MethodCacheInterceptor"> <property name="cache" ref="ehCache" /> <property name="noCacheMethod"> <list> <value>getNextSerialNo</value> <value>getNextNo</value> </list> </property> </bean> <!-- flush cache --> <bean id="methodCacheAfterAdvice" class="com.eclink.cache.MethodCacheAfterAdvice"> <property name="cache" ref="ehCache" /> <property name="noFlushCacheMethod"> <list> <value>NoFlushCache</value> </list> </property> </bean> <bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="methodCacheInterceptor" /> <property name="patterns"> <list> <value>com.eclink.service.*?\.find.*</value> <value>com.eclink.service.*?\.query.*</value> <value>com.eclink.service.*?\.select.*</value> <value>com.eclink.service.*?\.get.*</value> </list> </property> </bean> <bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="methodCacheAfterAdvice" /> <property name="patterns"> <list> <value>com.eclink.service.*?\.save.*</value> <value>com.eclink.service.*?\.insert.*</value> <value>com.eclink.service.*?\.update.*</value> <value>com.eclink.service.*?\.delete.*</value> <value>com.eclink.service.*?\.cancel.*</value> <value>com.eclink.service.*?\.confirm.*</value> </list> </property> </bean>
ehcache缓存配置文件:ehcache.xml
<diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" diskSpoolBufferSizeMB="30" maxElementsOnDisk="10000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="FDOL2_CACHE" maxElementsInMemory="1000" maxElementsOnDisk="10000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300000" timeToLiveSeconds="600000" memoryStoreEvictionPolicy="LFU" />
发表评论
-
使jQuery autocomplete支持中文搜索
2014-03-20 11:37 1872附件里是修改过的 jquery.autocomplete.js ... -
WEB开发中遇到的问题
2013-08-26 16:12 8961. Failed to load or instantiat ... -
java中拷贝删除文件或目录,
2013-08-20 08:38 810// 复制文件 public stati ... -
根据svn的ChangeLog打出更新包
2013-08-15 17:24 2102ChangeLog.txt r628 | zhoulz | ... -
简单又好用的Tomcat 页面权限控制
2013-08-08 09:02 1253不废话,就2个配置文件,直接上代码。 web.xml &l ... -
hibernate中OneToMany双向关联,不生成连接表,级联增删改配置
2013-04-08 15:29 6420One方配置: @OneToMany(fetch = Fet ... -
在jsp页面中,巧用struts2中的标签
2013-03-06 16:36 10591、set标签 <s:iterator value ... -
ibatis中 #和$的区别
2012-09-26 15:00 838据我理解是这样的 #是把传入的数据做类型转换,如果转换后拼接 ... -
a different object with the same identifier value was already associated with th
2012-09-26 11:13 1549原因:在保存(更新)对象newObj之前,已经通过id用get ... -
Write operations are not allowed in read-only mode (FlushMode.NEVER/MANUAL):
2012-07-27 11:42 9419遇到这个情况,我猜: 1、你一定使用的spring+hibe ... -
object references an unsaved transient instance - save the transient instance be
2012-07-27 11:16 1538今天在重构公司一个老项目的时候,遇到了这个异常,记录下: 很明 ...
相关推荐
以SpringBoot 为中心,模块化开发系统,用户可以随意删减除权限...复用,组装性强主要应用技术:spring Security+Ehcache+quartz+swagger2+Mysql5.6+springjdbc+druid+spring social+spring session + layerui+vue.js
,使用Spring+JPA+Velocity+Ehcache作为基础开发架构,应用SpringSecurity框架管理系统权限,结合URL重写技术静态化商城前台页面。 毕业设计是高等教育阶段学生在完成学业前所进行的一项重要学术任务,旨在检验学生...
代码是Ehcache的页面缓存、spring的缓存和Hibernate的缓存的应用,采用的是springMVC框架,数据库是MySQL
likejd:Shopping商城系统是采用Java语言开发的多用户商城系统,使用Spring + JPA + Velocity + Ehcache作为基础开发架构,应用SpringSecurity框架管理系统权限,结合URL合并技术静态化商城前台页面。商贸开发经验及...
同时使用了Struts2、Spring4、Hibernate4、log4j、slf4j、junit4、ehcache等库或框架,搭建一个最基本的项目原型。 三、 三大框架最新版本下载:截止2014-10-01 Struts2.3.6:发布于2014-05-03,目前的最新版本。...
FlyCms是一个类似知乎以问答为基础的完全开源的JAVA语言开发的社交网络建站程序,基于Spring Boot + Bootstrap3 + MyBatis + MYSQL + Solr + Ehcache应用架构,专注于社区内容的整理,归类和检索,其集合了问答,...
两级缓存在redis的方案上做一步优化,在缓存到远程redis的同时,缓存一份到本地进程ehcache(此处的ehcache不用做集群,避免组播带来的开销),取缓存的时候会先取本地,没有会向redis请求,这样会减少应用服务器<–...
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。Ehcache 是一种广泛使用的开源 Java 分布式缓存。主要面向通用缓存,Java EE 和轻量级容器。它具有内存和...
ehcache全解析 利用Spring和EHCache缓存结果 Hibernate+ehcache二级缓存技术 Spring基于注解的缓存配置--web应用实例 http://zjava.org.ru/
1、网关应用采用mina+spring+ehcache框架,主要功能是接受终端的tcp/udp链接,解析终端的上行消息以及封装平台下发的下行消息,本网关应用已历经并通过多次交通部部标部标的检测,性能稳定;同时网关采用json消息与...
Spring+JPA+Velocity+Ehcache作为基础开发架构,应用 SpringSecurity框架管理系统权限,结合URL重写技术静态化商城前 台页面。Shopping结合多年的电商开发经验及主流电商的功能特点, 注重系统易用性、功能性、...
本课程是基于大型互联网的真实架构进行讲解,秒杀系统技术架构 (Spring+SpringMVC+Mybatis+Dubbo+Druid+Ehcache+Redis+RabbitMQ+Zookeeper+jQuery+ajax) 技术涵盖JavaEE技术,分布式服务技术,高并发技术,缓存...
主要应用技术:SpringSecurity+Ehcache+quartz+swagger2+Mysql5.6.... 主要包含系统全方位监控,权限管理。定时任务,API在线接口,OSS云存储,第三方登录,在线支付,代码生成等内容。适合单机型框架开发
本实例的环境 eclipse + maven + spring + ehcache + junit EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。Ehcache是一种广泛使用的开 源Java分布式缓存。主要...
使用Spring+JPA+Velocity+Ehcache作为基础开发架构,应用SpringSecurity框架管理系统权限,结合URL重写技术静态化商城前台页面。 Shopping结合多年的电商开发经验及主流电商的功能特点,注重系统易用性、功能性、...
本文先通过Ehcache独立应用的范例来介绍它的基本使用方法,然后再介绍与Spring整合的方法。
-- 单realm应用。如果有多个realm,使用‘realms’属性代替 --> <property name="realm" ref="authorizingRealm" /> <property name="cacheManager" ref="shiroCacheManager" /> </bean> 服务器 web.xml...
它大大简化了在Spring应用中基于业界使用广泛的Ehacche-2.0版本实现缓存的技术,1.1.2版本的ehcache-spring-annotations刚刚发布不久,在本文中,我将会介绍如何在一个web工程时使用ehcache-spring-annotations实现...
以SpringBoot 为中心,模块化开发系统,用户可以随意删减除...复用,组装性强主要应用技术:spring Security+Ehcache+quartz+swagger2+Mysql5.6+springjdbc+druid+spring social+spring session + layerui+vue.js等。