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

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

问题现象

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

原因

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

解决方案

使用Ehcache的copyStrategy

Ehcache提供了copyOnRead=”true” copyOnWrite=”true”的配置属性。
作用是在读取或写入数据时,不使用原始数据,而是使用拷贝数据。
但是在使用该配置的时候,还要提供copyStrategy class属性,提供Copy策略。


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对象被创建出来之后,其内部的值是可以通过某些内部方法进行改变的。

Original: https://www.cnblogs.com/weilx/p/15970547.html
Author: 阿步呦
Title: 修改Ehcache缓存中取到的值,缓存中的值也被修改了

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579514/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • java AOP(面向切面)

    一:反射 public class Reflect{ public static void main(String [] args){ Class c = Class.fornam…

    Java 2023年6月5日
    071
  • 【软件构造】抽象数据类型ADT

    【软件构造】抽象数据类型ADT 1.前言 在Lab2中,涉及到了大量的ADT、RI、AF的设计,仅以此篇博客做一个小小的总结。🥰 2.ADT定义 除了java等编程语言自带的数据类…

    Java 2023年6月5日
    0132
  • Monitor(管程/监视器)详解

    说明 Monitor,直译为”监视器”,而操作系统领域一般翻译为”管程”。管程是指管理共享变量以及对共享变量操作的过程,让它们支持并…

    Java 2023年6月16日
    072
  • 接口

    JDK1.8之前 package com.gao.test.Test7; /* 1.类是类,接口是接口,他们是同一层次的概念。 2.接口中没有构造器 3.接口如何声明:interf…

    Java 2023年6月5日
    098
  • 自己挖坑自己埋

    谨用于记录自己在设计时由于考虑不周导致的隐患,阿门。 2021-07-19 新近上线了《智能串接》功能,该功能类似于各种工程项目中的quickStart功能,在该模块设计时留下了两…

    Java 2023年6月9日
    073
  • WinSCP和PuTTY(与Linux系统链接的工具)的安装和使用(含下载地址)

    该两款软件都是免费的 简介 WinSCP是一个Windows环境下使用SSH的开源图形化SFTP客户端。同时支持SCP协议。它的主要功能就是在本地与远程计算机间安全的复制文件。 安…

    Java 2023年6月6日
    085
  • Nginx 源码分析– 内存池(pool)的分析 二

    在上一篇中,以一张图(图1)介绍了nginx内存池管理函数的总体概况,并分析了底层支持函数和内存池(pool)管理所需要用到的一些数据结构。这里我们将来具体分析内存池管理功能函数。…

    Java 2023年6月15日
    091
  • 分布式锁

    分布式锁 本文整理自黑马程序员相关资料 问题的引入 在平时单服务的情况下,我们使用互斥锁可以保证同一时刻只有一个线程执行自己的业务。原理是,在JVM内部维护了一个锁监视器,锁监视器…

    Java 2023年6月8日
    076
  • 哈工大计算机系统大作业(2022)

    (论文封面略去) 本人博客链接(防扒): 本人CSDN博客: 何以牵尘的博客_CSDN博客-哈工大课内学习,哈工大精品课程笔记领域博主何以牵尘擅长哈工大课内学习,哈工大精品课程笔记…

    Java 2023年6月9日
    086
  • fastposter v2.8.2 发布 电商海报生成器

    fastposter v2.8.2 发布 电商海报生成器 fastposter海报生成器,电商海报编辑器,电商海报设计器,fast快速生成海报 海报制作 海报开发。二维码海报,图片…

    Java 2023年6月5日
    086
  • 《二十三种设计模式》通俗的创建型之单例设计模式

    单例模式(Singleton Pattern)是Java中 最简单的设计模式之一。 这种模式涉及到一个 单一的类,该类负责创建自己的对象,同时确保只有 单个对象被创建。这个类提供了…

    Java 2023年6月7日
    0110
  • SkyWalking分布式系统应用程序性能监控工具-中

    其他功能 性能剖析 在系统性能监控方法上,Skywalking 提出了代码级性能剖析这种在线诊断方法。这种方法基于一个高级语言编程模型共性,即使再复杂的系统,再复杂的业务逻辑,都是…

    Java 2023年6月5日
    0111
  • LeetCode.1185-一周中的星期几(Day of the Week)

    这是小川的第 415次更新,第 448篇原创 看题和准备 今天介绍的是 LeetCode算法题中 Easy级别的第 266题(顺位题号是 1185)。给定日期,返回该日期的星期几。…

    Java 2023年6月5日
    082
  • 擦肩而过

    你在路上擦肩而过的一个人,都有可能是别人朝思暮想还见不到的。 有没有一种可能,我上周去的肯德基,那个座位她曾经坐过? 有没有一种可能,今晚梦见她的时候,她也会梦见我? 可能都只是我…

    Java 2023年6月14日
    065
  • jQuery之过滤选择器

    过滤选择器 1.基本选择器 2.内容选择器 3.可见性选择器 4.子元素过滤器 过滤选择器简称:过滤器。它其实也是一种选择器,而这种选择器类似于CSS3(http://t.mb5u…

    Java 2023年6月6日
    0101
  • 物联网架构成长之路(59)-SpringBoot项目作为系统应用,自启动

    一、前言 开发完项目,一般调试都是在eclipse或者idea上运行服务的。但是要部署到服务器上,就需要后台运行和自启动等配置了。这里采用Debian系统作为演示。 二、后台运行 …

    Java 2023年5月30日
    080
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球