修改Ehcache缓存中取到的值,缓存中的值也被修改了

虚幻大学 xuhss 461℃ 0评论

Python微信订餐小程序课程视频

https://edu.csdn.net/course/detail/36074

Python实战量化交易理财系统

https://edu.csdn.net/course/detail/35475

1|*0***问题现象**

我们从Ehcache中取出缓存的对象,之后将对象中的属性进行了修改使用。等再次从缓存中拿到对象后,发现对象的值变成了上一次调用修改后的对象了。

2|*0***原因**

Ehcache中缓存的是原对象的引用,所以引用的内容被修改后cache内部的值也会被修改。

3|*0***解决方案**

使用Ehcache的copyStrategy

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 class="com.xxx.EhcacheCopyStrategy" />
cache>

copy策略类

public class EhcacheCopyStrategy implements ReadWriteCopyStrategy {
 @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对象

将我们的实体类设计成immutable的,如果需要修改就创建一个新的对象。

如何构建一个immutable对象

  • 确保fields中的成员都被private final修饰;private保证内部成员不会被外部直接访问,final保证成员在初始化后不会被assigned。
  • 不提供改变成员的方法,例如setXxx。
  • 使用final修饰自定义的类,确保类中的方法不会被重写。
  • 如果类中的某个成员是mutable类型的,那么在初始化该成员或者企图用get方法从外部对其观察时,应该使用深度拷贝,确保immutable。

String类

String类是java中典型的immutable数据类型,一个String对象一旦呗new出来后,就不能被修改,否则就会报assigned错误。
StringBuilder类的对象是mutable的数据类型,当一个StringBuilder对象被创建出来之后,其内部的值是可以通过某些内部方法进行改变的。

__EOF__

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dYhv1rKB-1646542230773)(https://blog.csdn.net/weilx/p/15970547.html)]lngrid ln grid 本文链接:https://blog.csdn.net/weilx/p/15970547.html关于博主:评论和私信会在第一时间回复。或者直接私信我。版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

转载请注明:xuhss » 修改Ehcache缓存中取到的值,缓存中的值也被修改了

喜欢 (0)

您必须 登录 才能发表评论!