本节commit地址:1ed2159
上一节我们实现了Kryo序列化,抱着学习的心态,本节基于Hessian协议来实现序列化,实现步骤和之前的Kryo类似,关于Hessian和Kryo的区别可以参考另一篇:https://blog.csdn.net/qq_38685503/article/details/114633168?spm=1001.2014.3001.5501
本节还会把Socket方式传输中用到的线程池封装成一个通用Util,要用到guava中的ThreadFactoryBuilder(),自定义线程名,方便出错定位问题。
Hessian序列化器
public class HessianSerializer implements CommonSerializer{
private static final Logger logger = LoggerFactory.getLogger(HessianSerializer.class);
@Override
public byte[] serialize(Object obj) {
HessianOutput hessianOutput = null;
try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()){
hessianOutput = new HessianOutput(byteArrayOutputStream);
hessianOutput.writeObject(obj);
return byteArrayOutputStream.toByteArray();
}catch (IOException e){
logger.error("序列化时有错误发生" + e);
throw new SerializeException("序列化时有错误发生");
}finally {
if(hessianOutput != null){
try {
hessianOutput.close();
}catch (IOException e){
logger.error("关闭output流时有错误发生" + e);
}
}
}
}
@Override
public Object deserialize(byte[] bytes, Class<?> clazz) {
HessianInput hessianInput = null;
try(ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes)){
hessianInput = new HessianInput(byteArrayInputStream);
return hessianInput.readObject();
}catch (IOException e){
logger.error("反序列化时有错误发生" + e);
throw new SerializeException("反序列化时有错误发生");
}finally {
if(hessianInput != null) {
hessianInput.close();
}
}
}
线程池工具类
public class ThreadPoolFactory {
/**
* 线程池参数
*/
private static final int CORE_POOL_SIZE = 10;
private static final int MAXIMUM_POOL_SIZE = 100;
private static final int KEEP_ALIVE_TIME = 1;
private static final int BLOCKING_QUEUE_CAPACITY = 100;
private ThreadPoolFactory(){
}
public static ExecutorService createDefaultThreadPool(String threadNamePrefix){
return createDefaultThreadPool(threadNamePrefix, false);
}
public static ExecutorService createDefaultThreadPool(String threadNamePrefix, Boolean daemon){
/**
* 设置上限为100个线程的阻塞队列
*/
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(BLOCKING_QUEUE_CAPACITY);
ThreadFactory threadFactory = createThreadFactory(threadNamePrefix, daemon);
return new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.MINUTES, workQueue, threadFactory);
}
/**
* @description 创建ThreadFactory,如果threadNamePrefix不为空则使用自建ThreadFactory,否则使用defaultThreadFactory
* @param threadNamePrefix 作为创建的线程名字的前缀,指定有意义的线程名称,方便出错时回溯
* @param daemon 指定是否为Daemon Thread(守护线程),当所有的非守护线程结束时,程序也就终止了,同时会杀死进程中的所有守护线程
* @return [java.util.concurrent.ThreadFactory]
* @date [2021-03-10 17:50]
*/
private static ThreadFactory createThreadFactory(String threadNamePrefix, Boolean daemon) {
if (threadNamePrefix != null) {
if (daemon != null) {
//利用guava中的ThreadFactoryBuilder自定义创建线程工厂
return new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").setDaemon(daemon).build();
} else {
return new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").build();
}
}
return Executors.defaultThreadFactory();
}
}
本节over……