修改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 class="com.xxx.EhcacheCopyStrategy" />
</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对象被创建出来之后,其内部的值是可以通过某些内部方法进行改变的。
修改Ehcache缓存中取到的值,缓存中的值也被修改了的更多相关文章
- 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】
多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...
- 【算法与数据结构】在n个数中取第k大的数(基础篇)
(转载请注明出处:http://blog.csdn.net/buptgshengod) 题目介绍 在n个数中取第k大的数(基础篇),之所以叫基础篇是因为还有很多更高级的算法,这些 ...
- Mybatis的二级缓存、使用Redis做二级缓存
目录 什么是二级缓存? 1. 开启二级缓存 如何使用二级缓存: userCache和flushCache 2. 使用Redis实现二级缓存 如何使用 3. Redis二级缓存源码分析 什么是二级缓存? ...
- hibernate的二级缓存----collection和query的二级缓存
collection二级缓存: 不使用集合的二级缓存时: 运行下面的代码: @Test public void testCollectionSecondLevelCache1(){ Departmen ...
- SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存
1. 使用Redis 在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖. pom.xml文件如下 <dependency> <groupId&g ...
- react+dva 全局model中异步获取数据state在组件中取不到值
先上结论,不是取不到,是写法有问题. 全文分4部分,1是问题描述,2是一开始的解决想法(错误做法),3是问题产生原因的思考,4是正常解决方法.只想看结论直接跳4 1.问题描述 接触react dva一 ...
- ComboboxColumn取值——Winform中DataGridView中某一列使用下拉框
ComboboxColumn的用法网上很多,绑定数据源都很简单,这里我遇到的是.不绑定数据源,即所有comobox的绑定都是固定的几个数据: 可以看到没有绑定任何数据源, ,在后台cs中取到下拉框的值 ...
- DataGrid中取HyperLinkColumn列的值,处理DataGrid中绑定的特殊字符
DataGrid中取HyperLinkColumn列的值. /// <summary> /// 对datagrid中标签进行编码,处理特殊字符 /// </summary> / ...
- action中list传到JSP中取不到值的问题
今天遇到了这个问题 action中list传到JSP中取不到值 搞了半天是因为我在JSP中取值的的时候 <s:iterator value="shlist" var=&qu ...
随机推荐
- 微信小程序入门教程之三:脚本编程
这个系列教程的前两篇,介绍了小程序的项目结构和页面样式. 今天,接着往下讲,教大家为小程序加入 JavaScript 脚本,做出动态效果,以及如何跟用户互动.学会了脚本,就能做出复杂的页面了. 本篇的 ...
- 数据库备份还原 mysqldump
1.备份全部数据库的数据和结构mysqldump -uroot -p123456 --all-databases >all.bakmysqldump -uroot -p123456 -A > ...
- 裸k8s搭建中遇到的两个坑
在装docker的时候报错了,需要先安装selinux版本.才能安装容器. 需要按照提示安装这个包. 采用强制安装.rpm -ivh 包名字 --force --nodeps 在k8s的master上 ...
- netstat in Linux
# netstat -unlt Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address ...
- LoadRunner编写socket性能测试脚本
利用LoadRunner编写socket性能测试脚本 一.概述 Loadrunner拥有极为丰富的工具箱,供予我们制造出各种奇妙魔法的能力.其中就有此次要讨论的socket套接字操作. 二.socke ...
- Dapr 和 Azure Functions : Hello world
本篇文章内容来自 https://charliedigital.com/2021/07/01/dapr-and-azure-functions-part-1-hello-world/ ,是按这篇文章的 ...
- Maven 项目报出警告:Warning:java: source value 1.5 is obsolete and will be removed in a future release
感谢原文作者:Hxinguan 原文链接:https://www.cnblogs.com/Hxinguan/p/6132446.html 问题: 1.创建maven项目的时候,jdk版本是1.5版本, ...
- drop、delete和truncate三者的区别
相同点:1.truncate和不带where子句的delete.以及drop都会删除表内的数据.2.drop.truncate都是DDL语句(数据定义语言),执行后会自动提交.不同点:1. trunc ...
- 《PHP程序员面试笔试宝典》——什么是职场暗语?
本文摘自<PHP程序员面试笔试宝典> 文末有该书电子版下载. 随着求职大势的变迁发展,以往常规的面试套路因为过于单调.简明,已经被众多"面试达人"们挖掘出了各种&quo ...
- Solution Set -「ABC 217」
大家好屑兔子又来啦! [A - Lexicographic Order] 说个笑话,\(\color{black}{\text{W}}\color{red}{\text{alkingDead} ...