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

博客 分享
0 208
优雅殿下
优雅殿下 2022-03-06 10:56:12
悬赏:0 积分 收藏

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

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

问题现象

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

原因

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

解决方案

使用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  /></cache>

copy策略类

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对象

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

如何构建一个immutable对象

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

String类

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

posted @ 2022-03-06 10:28 阿步呦 阅读(5) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员