序列化的5w2h分析
what:序列化是一种将java对象流化的机制
how:将一个实现了Serializable接口的对象的状态写入byte[],传输到另外一个地方,将其读出进行反序列化得对象(含状态)。状态就是类中的属性是含有值的。
why:方便对象在网络间进行传播,并且可以随时把对象持久化到数据库、文件等系统里
when:对象需要远程过程调用,缓存到文件或DB中(hessian,rmi,ejb)
where:发送接口处,写入文件的入口处
who:发送端序列化,接收端反序列化
how much:序列化本身是昂贵的,但软件工程本身是复杂,在解藕与性能之间架构师要做一个判断。
实验环境
1 |
SerializeException 可自定义,继承runtimeException |
hessian序列化工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
package com.uet.common.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import com.caucho.hessian.io.HessianSerializerInput; import com.caucho.hessian.io.HessianSerializerOutput; import com.uet.common.exception.SerializeException; public class HessianObjectSerializeUtil { /** * * 纯hessian序列化 * * @param <T> * * @param object * * @return * * @throws Exception */ public static <T> byte[] serialize(T object) { if (object == null) { throw new NullPointerException(); } byte[] results = null; ByteArrayOutputStream os = null; HessianSerializerOutput hessianOutput = null; try { os = new ByteArrayOutputStream(); hessianOutput = new HessianSerializerOutput(os); //write本身是线程安全的 hessianOutput.writeObject(object); os.close(); results = os.toByteArray(); } catch (Exception e) { throw new SerializeException(e); } finally { try { if (os != null) os.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return results; } /** * * 纯hessian反序列化 * * @param bytes * * @return * * @throws Exception */ @SuppressWarnings("unchecked") public static <T> T deserialize(Class<T> resultClass, byte[] bytes) { if (bytes == null) { throw new NullPointerException(); } T result = null; ByteArrayInputStream is = null; try { is = new ByteArrayInputStream(bytes); HessianSerializerInput hessianInput = new HessianSerializerInput(is); result = (T) hessianInput.readObject(); } catch (Exception e) { throw new SerializeException(e); } finally { try { if (is != null) is.close(); } catch (IOException e) { throw new SerializeException(e); } } return result; } } |
java自带的序列化工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
package com.uet.common.utils; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import com.uet.common.exception.SerializeException; public class ObjectsSerializeUtil{ public static <T> byte[] serialize(T value) { if (value == null) { throw new NullPointerException("Can‘t serialize null"); } byte[] result = null; ByteArrayOutputStream bos = null; ObjectOutputStream os = null; try { bos = new ByteArrayOutputStream(); os = new ObjectOutputStream(bos); os.writeObject(value); os.close(); bos.close(); result = bos.toByteArray(); } catch (IOException e) { throw new IllegalArgumentException("Non-serializable object", e); } finally { close(os); close(bos); } return result; } @SuppressWarnings("unchecked") public static <T> T deserialize(Class<T> resultClass,byte[] in) { T result = null; ByteArrayInputStream bis = null; ObjectInputStream is = null; try { if (in != null) { bis = new ByteArrayInputStream(in); is = new ObjectInputStream(bis); result = (T) is.readObject(); is.close(); bis.close(); } } catch (IOException e) { throw new SerializeException(String.format("Caught IOException decoding %d bytes of data", in == null ? 0 : in.length) + e); } catch (ClassNotFoundException e) { throw new SerializeException(String.format("Caught CNFE decoding %d bytes of data", in == null ? 0 : in.length) + e); } finally { close(is); close(bis); } return result; } public static void close(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception e) { throw new SerializeException(e); } } } } |
实验运行的类(BaseGrade您可以自己定义,但要实现Serializable接口)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package com.uet.common.utils; import com.uet.course.entity.BaseGrade; public class SerializeTest { private static int count=10000; public static void main(String[] args) throws Exception { /*BaseGrade grade = new BaseGrade(); grade.setId(120L+10); grade.setName("唔年纪"); grade.init(); byte[] results=HessianObjectSerializeUtil.serialize(grade);*/ //System.out.println(results.length); hessianObjectSerialize(); javaObjectSerialize(); } public static void hessianObjectSerialize(){ long start = System.currentTimeMillis(); for(int i=0;i<count;i++){ BaseGrade grade = new BaseGrade(); grade.setId(120L+i); grade.setName("唔年纪"); grade.init(); byte[] results=HessianObjectSerializeUtil.serialize(grade); BaseGrade result=HessianObjectSerializeUtil.deserialize(BaseGrade.class,results); //System.out.println(result.getId()); } long end = System.currentTimeMillis(); System.out.println("hessianObjectSerialize耗时:"+ ((end - start) / 1000.0) + " seconds"); } public static void javaObjectSerialize(){ long start = System.currentTimeMillis(); for(int i=0;i<count;i++){ BaseGrade grade = new BaseGrade(); grade.setId(120L+i); grade.setName("唔年纪"); grade.init(); byte[] results=ObjectsSerializeUtil.serialize(grade); BaseGrade result=ObjectsSerializeUtil.deserialize(BaseGrade.class,results); //System.out.println(result.getId()); } long end = System.currentTimeMillis(); System.out.println("javaObjectSerialize耗时:"+ ((end - start) / 1000.0) + " seconds"); } } |
序列化的字节260btye
实验结果
循环1次(运行10次平均结果):
hessianObjectSerialize耗时:0.05 seconds
javaObjectSerialize耗时:0.01 seconds
循环10次(运行10次平均结果):
hessianObjectSerialize耗时:0.06 seconds
javaObjectSerialize耗时:0.015 seconds
循环100次(运行10次平均结果):
hessianObjectSerialize耗时:0.074 seconds
javaObjectSerialize耗时:0.04 seconds
循环1000次(运行10次平均结果):
hessianObjectSerialize耗时:0.162 seconds
javaObjectSerialize耗时:0.123 seconds
循环10000次(运行10次平均结果):
hessianObjectSerialize耗时:0.6 seconds
javaObjectSerialize耗时:0.47 seconds
循环100000次
hessianObjectSerialize耗时:4.668 seconds
javaObjectSerialize耗时:4.144 seconds
实验结论
java自身所带的方法明显比hessian自带的序列化效率更高。