/* * Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved */ package com.xingguo.java.beans.properties; import java.beans.*; import java.io.Serializable; /** * Person * * @author guoxing * @date 2020/11/24 11:28 AM * @since */ public class Person implements Serializable { private String name; private int age; /** * javabeans - persistence * 首先要求实现 java.io.Serializable * 对于 不需要持久化的属性 要求 使用 "transient" 关键字保证其不会被持久化 */ // 设置当前Bean的属性变化支持工具 // 强制属性更新 private final transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this); // 勉强属性更新 private final transient VetoableChangeSupport vetoableChangeSupport = new VetoableChangeSupport(this); public String getName() { return name; } /** * 当名称属性发生变化时, * * @param name */ public void setName(String name) { String oldVal = this.name; String newVal = name; // 创建属性变更事件 PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(this, "name", oldVal, newVal); // 勉强属性 fireVetoableChange(propertyChangeEvent); this.name = name; // 强迫事件变更机制 // 强迫事件变更发生在 属性成功变更之后 // 属性变更后发布事件 // 发布事件 propertyChangeSupport.firePropertyChange(propertyChangeEvent); } public void fireVetoableChange(PropertyChangeEvent event) { try { // 校验要求name 不能为纯粹的数字 String propertyName = event.getPropertyName(); if ("name".equals(propertyName) && isNumeric(String.valueOf(event.getNewValue()))) { throw new PropertyVetoException("name属性要求不能为纯数字", event); } vetoableChangeSupport.fireVetoableChange(event); } catch (PropertyVetoException propertyVetoException) { throw new RuntimeException(propertyVetoException); } } public void addVetoableChangeListener(VetoableChangeListener listener) { } public void removeVetoableChangeListener(VetoableChangeListener listener) { } public void addPropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { propertyChangeSupport.removePropertyChangeListener(listener); } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } public static boolean isNumeric(String str) { if (str == null) { return false; } else { int sz = str.length(); for (int i = 0; i < sz; ++i) { if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } } }
/* * Copyright (c) 2020, guoxing, Co,. Ltd. All Rights Reserved */ package com.xingguo.java.beans.persistence; import com.xingguo.java.beans.properties.Person; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import java.io.*; import java.nio.file.FileSystemNotFoundException; import java.util.Properties; import java.util.stream.Stream; /** * PersonPersistence * * @author guoxing * @date 2020/11/24 10:34 PM * @since */ @Slf4j public class PersonPersistence { public static void main(String[] args) throws IOException, ClassNotFoundException { Person person = new Person(); person.setAge(18); person.setName("guoxing"); // 获取当前编译路径 // 需要获取到 启动命令中的 -classpath 中的 classes文件夹 Properties properties = System.getProperties(); String classpath = System.getProperty("java.class.path"); String[] split = classpath.split(":"); String currentCompilerClassPath = Stream.of(split) .filter(s -> StringUtils.endsWithIgnoreCase(s, "classes")) .map(File::new) // 转换为文件 .filter(File::isDirectory) .filter(File::canRead) .filter(File::canWrite) .map(File::getAbsolutePath) .findFirst() .orElseThrow(FileSystemNotFoundException::new); // OutputStream outputStream = new FileOutputStream(new File(currentCompilerClassPath, "person.tmp")); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream); objectOutputStream.writeObject(person); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(outputStream.toByteArray()); ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); // 通过断点可以看出来 对于 未使用 "transient" 关键字的属性,通过流传递之后会得到相应的数据 // 而对于使用了 "transient" 关键字的属性, 在转换之后就会变成其默认值 Person newPerson = (Person) objectInputStream.readObject(); log.info("{}", newPerson); } }
persistence 重点在于 序列化传输后的数据是否存在