我们从Ehcache中取出缓存的对象,之后将对象中的属性进行了修改使用。等再次从缓存中拿到对象后,发现对象的值变成了上一次调用修改后的对象了。
Ehcache中缓存的是原对象的引用,所以引用的内容被修改后cache内部的值也会被修改。
Ehcache提供了copyOnRead="true" copyOnWrite="true"的配置属性。
作用是在读取或写入数据时,不使用原始数据,而是使用拷贝数据。
但是在使用该配置的时候,还要提供copyStrategy class属性,提供Copy策略。
<cache name="bannerCache" eternal="false" maxElementsInMemory="50" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="300" timeToLiveSeconds="300" memoryStoreEvictionPolicy="LFU" copyOnRead="true" copyOnWrite="true"> <copyStrategy /></cache>public class EhcacheCopyStrategy implements ReadWriteCopyStrategy<Element> { @Override public Element copyForWrite(Element value) { if(value != null){ Object temp=(Serializable)value.getObjectValue(); try { return new Element(value.getObjectKey(),deepCopy(temp)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return value; } @Override public Element copyForRead(Element storedValue) { if(storedValue != null){ Object temp=(Serializable)storedValue.getObjectValue(); try { return new Element(storedValue.getObjectKey(),deepCopy(temp)); } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return storedValue; } private Object deepCopy(Object src) throws IOException, ClassNotFoundException { ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(byteOut); out.writeObject(src); ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); ObjectInputStream in = new ObjectInputStream(byteIn); return in.readObject(); }}将我们的实体类设计成immutable的,如果需要修改就创建一个新的对象。
String类是java中典型的immutable数据类型,一个String对象一旦呗new出来后,就不能被修改,否则就会报assigned错误。
StringBuilder类的对象是mutable的数据类型,当一个StringBuilder对象被创建出来之后,其内部的值是可以通过某些内部方法进行改变的。