这一阵子一直在忙项目,现在终于可以静下心来总结这一段时间的开发心得,新年第一篇打算讲下我犯的一次低级失误,或者可以说是疏忽,希望能给大家一些帮助 ~
最近,笔者也有一些事不顺心,人生不如意事十之八九,努力过了,该熬的夜熬过了,不后悔就够了。希望大家在新年顺顺利利 ~
// 调用RPC服务获取Mission对象 ResponseDTO<Mission> res = missionService.getMissionById(missionId); // 下沉后直接通过缓存获取对象(RPC服务原有的方法) Mission mission = missionCache.getMissionById(missionId); 复制代码
// set mission对象属性 (其实set很不合理,应该是一个BO) mission.setA(A); mission.setB(B); // 根据mission对象属性触发业务逻辑 // ... 复制代码
根据上述改动,会发现我只是把RPC调用的逻辑下沉到了服务方,调用了服务方的方法获取了 mission
对象,但是出现了问题,很显然,导致的直接结果是 显示错乱
。
想必,大家都会知道原因,如下:
1、RPC获取的对象经过反序列化,不是从数据库取出的对象,set对象属性不会影响缓存中的值。 2、缓存里取出来的是数据库取出的对象(缓存的key为missionId)是从数据库取出的对象,set对象属性会影响到其他用户的访问结果。
package serialization;// Java code for serialization and deserialization // of a Java object import java.io.*; class Demo implements java.io.Serializable { public int a; public String b; // Default constructor public Demo(int a, String b) { this.a = a; this.b = b; } } public class TestObject { public static void main(String[] args) { Demo object = new Demo(1, "geeksforgeeks"); String filename = "file.ser"; // Serialization try { //Saving of object in a file FileOutputStream file = new FileOutputStream(filename); ObjectOutputStream out = new ObjectOutputStream(file); // Method for serialization of object out.writeObject(object); out.close(); file.close(); System.out.println("Object has been serialized"); System.out.println(object.toString()); } catch(IOException ex) { System.out.println("IOException is caught"); } Demo object1 = null; // Deserialization try { // Reading the object from a file FileInputStream file = new FileInputStream(filename); ObjectInputStream in = new ObjectInputStream(file); // Method for deserialization of object object1 = (Demo)in.readObject(); in.close(); file.close(); System.out.println("Object has been deserialized "); System.out.println(object1.toString()); } catch(IOException ex) { System.out.println("IOException is caught"); } catch(ClassNotFoundException ex) { System.out.println("ClassNotFoundException is caught"); } } } 复制代码
Object has been serialized serialization.Demo@23fc625e Object has been deserialized serialization.Demo@1f17ae12 复制代码
在Java语言中,数据类型分为值类型(基本数据类型)和引用类型,值类型包括int、double、byte、boolean、char等简单数据类型,引用类型包括类、接口、数组等复杂类型。浅克隆和深克隆的主要区别在于是否支持引用类型的成员变量的复制,下面将对两者进行详细介绍。
get/set
方法 clonable
接口 class Demo implements Cloneable { public int a; public String b; // Default constructor public Demo(int a, String b) { this.a = a; this.b = b; } @Override protected Object clone() { Demo demo = null; try { demo = (Demo) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return demo; } public static void main(String[] args) { Demo demo1 = new Demo(1, "1"); Demo demo2 = (Demo) demo1.clone(); System.out.println(demo1 == demo2); } } 复制代码
apache
或者 spring
的工具类, BeanUtils
1、spring (org.springframework.beans.BeanUtils) 2、apache commons-beanutils(org.apache.commons.beanutils.BeanUtils)
// org.springframework.beans.BeanUtils, // a拷贝到b // org.apache.commons.beanutils.BeanUtils, // b拷贝到a BeanUtils.copyProperties(a, b); 复制代码