From a67f6b691843ae84c0ec03888ff418c41d03dc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B1=AA=E4=BA=91=E6=98=8A?= Date: Thu, 13 Aug 2020 22:34:09 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=BE=AE=E6=9C=8D=E5=8A=A1=E5=A4=9A?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E4=B8=8B=E5=8D=95=E5=8F=B7=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/iservice/base/ISynchronizedService.java | 10 + .../api/iservice/busi/ISysOrderNoRuleService.java | 8 + .../controller/base/WhiteController.java | 49 ++++- .../controller/busi/SysOrderNoRuleController.java | 24 ++- .../serviceimpl/base/SynchronizedService.java | 14 ++ .../serviceimpl/busi/SysOrderNoRuleService.java | 51 ++++- .../i3plus/core/apiservice/util/CloneTool.java | 231 +++++++++++++++++++++ 7 files changed, 380 insertions(+), 7 deletions(-) create mode 100644 modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/CloneTool.java diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java index 317e832..b25fdd3 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/base/ISynchronizedService.java @@ -3,6 +3,8 @@ package cn.estsh.i3plus.core.api.iservice.base; import cn.estsh.i3plus.pojo.platform.bean.SysOrderNoRule; import io.swagger.annotations.ApiOperation; +import java.util.List; + /** * @Description : * @Reference : @@ -20,4 +22,12 @@ public interface ISynchronizedService { @ApiOperation(value = "根据code查询最新单号规则") SysOrderNoRule nextOrderNo(String code); + /** + * 根据单号代码获取单号信息 + * @param code 单号代码 + * @return 单号信息 + */ + @ApiOperation(value = "根据code查询最新单号规则") + List nextOrderNo(String code, int num); + } diff --git a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java index a177138..ce61dbb 100644 --- a/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java +++ b/modules/i3plus-core-api/src/main/java/cn/estsh/i3plus/core/api/iservice/busi/ISysOrderNoRuleService.java @@ -64,6 +64,14 @@ public interface ISysOrderNoRuleService { SysOrderNoRule doGetSysOrderNoRuleCode(String code); /** + * 根据单号代码获取单号信息 + * @param code 单号代码 + * @return 单号信息 + */ + @ApiOperation(value = "根据code查询最新单号规则") + List doGetSysOrderNoRuleByCodeAndNum(String code,int num); + + /** * 根据id修改单号规则状态 * @param id 单号ID * @param status 单号状态 diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java index 7674183..36ea43f 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/base/WhiteController.java @@ -38,6 +38,12 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.stream.Collectors; + +import static cn.estsh.i3plus.platform.common.util.CommonConstWords.REDIS_PREFIX_LOCK_BATCH_GET_ORDER_NO; +import static cn.estsh.i3plus.platform.common.util.CommonConstWords.REDIS_PREFIX_LOCK_GET_ORDER_NO; /** * @Description : @@ -63,6 +69,9 @@ public class WhiteController extends CoreBaseController { private ISystemLoginService systemLoginService; @Autowired + private ISysOrderNoRuleService sysOrderNoRuleService; + + @Autowired private ISysUserService userService; @Autowired @@ -92,7 +101,7 @@ public class WhiteController extends CoreBaseController { @Autowired private SysUserPasswordUtil userPasswordUtil; - @Resource(name=CommonConstWords.IMPP_REDIS_RES) + @Resource(name = CommonConstWords.IMPP_REDIS_RES) private ImppRedis redisRes; @Autowired @@ -398,15 +407,50 @@ public class WhiteController extends CoreBaseController { @GetMapping(value = "/sys-order-no-rule/get-order-no/{code}") @ApiOperation(value = "根据单号规则代码,生成单号") public ResultBean getOrderNo(@PathVariable("code") String code) { + Lock lock = redisCore.getFairLock(REDIS_PREFIX_LOCK_GET_ORDER_NO); try { ValidatorBean.checkNotNull(code, "code不能为空"); + // 获取锁 + lock.lock(); + SysOrderNoRule sysOrderNoRule = synchronizedService.nextOrderNo(code); return ResultBean.success("操作成功").setResultObject(sysOrderNoRule).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); } catch (ImppBusiException busExcep) { return ResultBean.fail(busExcep); } catch (Exception e) { return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } finally { + lock.unlock(); + } + } + + /** + * 根据单号规则代码,生成单号 + * + * @param code 单号规则代码 + * @param num 生成数量 + * @return 处理结果 + */ + @GetMapping(value = "/sys-order-no-rule/get-order-no/{code}/{num}") + @ApiOperation(value = "根据单号规则代码,生成单号") + public ResultBean getOrderNo(@PathVariable("code") String code, @PathVariable("num") Integer num) { + Lock lock = redisCore.getFairLock(REDIS_PREFIX_LOCK_BATCH_GET_ORDER_NO); + try { + ValidatorBean.checkNotNull(code, "code不能为空"); + ValidatorBean.checkNotZero(num, "次数不能为零"); + + // 获取锁 + lock.tryLock(15, TimeUnit.SECONDS); + + List orderNoList = synchronizedService.nextOrderNo(code, num).stream().map(SysOrderNoRule::getOrderNo).collect(Collectors.toList()); + return ResultBean.success("操作成功").setResultList(orderNoList).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); + } catch (ImppBusiException busExcep) { + return ResultBean.fail(busExcep); + } catch (Exception e) { + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } finally { + lock.unlock(); } } @@ -435,6 +479,7 @@ public class WhiteController extends CoreBaseController { /** * 获取登录平台信息 + * * @return */ private CommonEnumUtil.LOG_LOGIN_PLATFORM getLoginPlatform(){ @@ -514,6 +559,7 @@ public class WhiteController extends CoreBaseController { /** * 根据条件分页查询用户信息 + * * @param model 查询条件 * @return 处理结果 */ @@ -554,6 +600,7 @@ public class WhiteController extends CoreBaseController { /** * 缺失资源开关 + * * @return */ @AnnoIgnoreLog diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysOrderNoRuleController.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysOrderNoRuleController.java index 4c145c5..bfbdb76 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysOrderNoRuleController.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/controller/busi/SysOrderNoRuleController.java @@ -12,6 +12,7 @@ import cn.estsh.i3plus.platform.common.tool.StringTool; import cn.estsh.i3plus.platform.common.tool.ZipTool; import cn.estsh.i3plus.platform.common.util.CommonConstWords; import cn.estsh.i3plus.platform.common.util.PlatformConstWords; +import cn.estsh.i3plus.pojo.base.bean.ImppFile; import cn.estsh.i3plus.pojo.base.bean.ListPager; import cn.estsh.i3plus.pojo.base.common.Pager; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; @@ -22,7 +23,6 @@ import cn.estsh.impp.framework.base.controller.CoreBaseController; import cn.estsh.impp.framework.boot.exception.ImppBusiException; import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; import cn.estsh.impp.framework.boot.fileservice.ImppFileService; -import cn.estsh.i3plus.pojo.base.bean.ImppFile; import cn.estsh.impp.framework.boot.util.ImppRedis; import cn.estsh.impp.framework.boot.util.ResultBean; import cn.estsh.impp.framework.boot.util.ValidatorBean; @@ -38,6 +38,11 @@ import java.io.File; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.stream.Collectors; + +import static cn.estsh.i3plus.platform.common.util.CommonConstWords.REDIS_PREFIX_LOCK_GET_ORDER_NO; /** * @Description :系统单号规则管理服务 @@ -388,15 +393,21 @@ public class SysOrderNoRuleController extends CoreBaseController { @GetMapping(value = "/get-order-no/{code}") @ApiOperation(value = "根据单号规则代码,生成单号") public ResultBean getOrderNo(@PathVariable("code") String code) { + Lock lock = redisCore.getLock(REDIS_PREFIX_LOCK_GET_ORDER_NO); try { ValidatorBean.checkNotNull(code, "code不能为空"); + // 获取锁 + lock.tryLock(10, TimeUnit.SECONDS); + SysOrderNoRule sysOrderNoRule = synchronizedService.nextOrderNo(code); return ResultBean.success("操作成功").setResultObject(sysOrderNoRule).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); } catch (ImppBusiException busExcep) { return ResultBean.fail(busExcep); } catch (Exception e) { return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } finally { + lock.unlock(); } } @@ -409,19 +420,22 @@ public class SysOrderNoRuleController extends CoreBaseController { @GetMapping(value = "/get-order-no/{code}/{num}") @ApiOperation(value = "根据单号规则代码,生成单号") public ResultBean getOrderNo(@PathVariable("code") String code,@PathVariable("num") Integer num) { + Lock lock = redisCore.getLock(REDIS_PREFIX_LOCK_GET_ORDER_NO); try { ValidatorBean.checkNotNull(code, "code不能为空"); ValidatorBean.checkNotZero(num,"次数不能为零"); - List orderNoList = new ArrayList<>(); - for (int i = 0; i < num; i++) { - orderNoList.add(synchronizedService.nextOrderNo(code).getOrderNo()); - } + // 获取锁 + lock.tryLock(10, TimeUnit.SECONDS); + + List orderNoList = synchronizedService.nextOrderNo(code,num).stream().map(SysOrderNoRule::getOrderNo).collect(Collectors.toList()); return ResultBean.success("操作成功").setResultList(orderNoList).setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()); } catch (ImppBusiException busExcep) { return ResultBean.fail(busExcep); } catch (Exception e) { return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } finally { + lock.unlock(); } } } diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java index 95904f8..4edf7d5 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/base/SynchronizedService.java @@ -6,6 +6,8 @@ import cn.estsh.i3plus.pojo.platform.bean.SysOrderNoRule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + /** * @Description : * @Reference : @@ -23,4 +25,16 @@ public class SynchronizedService implements ISynchronizedService { public synchronized SysOrderNoRule nextOrderNo(String code) { return sysOrderNoRuleService.doGetSysOrderNoRuleCode(code); } + + /** + * 根据单号代码获取单号信息 + * + * @param code 单号代码 + * @param num + * @return 单号信息 + */ + @Override + public synchronized List nextOrderNo(String code, int num) { + return sysOrderNoRuleService.doGetSysOrderNoRuleByCodeAndNum(code,num); + } } diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java index 4d5e82e..40c4cc4 100644 --- a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/serviceimpl/busi/SysOrderNoRuleService.java @@ -1,7 +1,9 @@ package cn.estsh.i3plus.core.apiservice.serviceimpl.busi; import cn.estsh.i3plus.core.api.iservice.busi.ISysOrderNoRuleService; +import cn.estsh.i3plus.core.apiservice.util.CloneTool; import cn.estsh.i3plus.core.apiservice.util.OrderNoMakeUtil; +import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; import cn.estsh.i3plus.platform.common.tool.StringTool; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.bean.ListPager; @@ -13,13 +15,13 @@ import cn.estsh.i3plus.pojo.platform.bean.SysOrderNoRule; import cn.estsh.i3plus.pojo.platform.repository.SysOrderNoRuleRepository; import cn.estsh.i3plus.pojo.platform.sqlpack.CoreHqlPack; import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder; -import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.List; /** @@ -114,6 +116,53 @@ public class SysOrderNoRuleService implements ISysOrderNoRuleService { } } + /** + * 根据单号代码获取单号信息 + * + * @param code 单号代码 + * @param num + * @return 单号信息 + */ + @Override + public synchronized List doGetSysOrderNoRuleByCodeAndNum(String code, int num) { + SysOrderNoRule sysOrderNoRule = sysOrderNoRuleRDao.getByProperty("orderNoRuleCode", code); + sysOrderNoRuleRDao.detachObject(sysOrderNoRule); + List resultList = new ArrayList<>(); + + if (sysOrderNoRule == null) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION_DATA_NOT_EXIT.getCode()) + .setErrorDetail("[" + code + "]规则代码不存在存在") + .setErrorSolution("请重新输入规则代码") + .build(); + } else if (sysOrderNoRule.getOrderNoRuleStatus() == CommonEnumUtil.TRUE_OR_FALSE.FALSE.getValue()) { + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode()) + .setErrorDetail("[" + code + "]单号规则已禁用") + .setErrorSolution("请重新输入规则代码") + .build(); + } else { + try { + for (int i = 0; i < num; i++) { + sysOrderNoRule = OrderNoMakeUtil.next((SysOrderNoRule) CloneTool.clone(sysOrderNoRule)); + resultList.add(sysOrderNoRule); + } + }catch (Exception e){ + LOGGER.error("单号生成异常:",e); + throw ImppExceptionBuilder.newInstance() + .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode()) + .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode()) + .setErrorDetail("单号生成异常 %s",e.getMessage()) + .build(); + } + + sysOrderNoRuleRDao.update(sysOrderNoRule); + return resultList; + } + } + @Override public void updateSysOrderNoRuleCodeStatusById(Long id, Integer status) { sysOrderNoRuleRDao.updateByProperties("id", id, "orderNoRuleStatus", status); diff --git a/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/CloneTool.java b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/CloneTool.java new file mode 100644 index 0000000..cf6b035 --- /dev/null +++ b/modules/i3plus-core-apiservice/src/main/java/cn/estsh/i3plus/core/apiservice/util/CloneTool.java @@ -0,0 +1,231 @@ +package cn.estsh.i3plus.core.apiservice.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; + +/** + * @Description : + * @Reference : + * @Author : yunhao + * @CreateDate : 2020-08-12 13:44 + * @Modify: + **/ +public class CloneTool { + + public static final Logger LOGGER = LoggerFactory.getLogger(CloneTool.class); + + /** + * 无需进行复制的特殊类型数组 + */ + static Class[] needlessCloneClasses = new Class[]{String.class,Boolean.class,Character.class,Byte.class,Short.class, + Integer.class,Long.class,Float.class,Double.class,Void.class,Object.class,Class.class + }; + /** + * 判断该类型对象是否无需复制 + * @param c 指定类型 + * @return 如果不需要复制则返回真,否则返回假 + */ + private static boolean isNeedlessClone(Class c){ + if(c.isPrimitive()){//基本类型 + return true; + } + for(Class tmp:needlessCloneClasses){//是否在无需复制类型数组里 + if(c.equals(tmp)){ + return true; + } + } + return false; + } + + /** + * 尝试创建新对象 + * @param value 原始对象 + * @return 新的对象 + * @throws IllegalAccessException + */ + private static Object createObject(Object value) throws IllegalAccessException{ + try { + return value.getClass().newInstance(); + } catch (InstantiationException e) { + return null; + } catch (IllegalAccessException e) { + throw e; + } + } + + /** + * 复制对象数据 + * @param value 原始对象 + * @param level 复制深度。小于0为无限深度,即将深入到最基本类型和Object类级别的数据复制; + * 大于0则按照其值复制到指定深度的数据,等于0则直接返回对象本身而不进行任何复制行为。 + * @return 返回复制后的对象 + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static Object clone(Object value,int level) throws IllegalAccessException, InstantiationException { + if(value==null){ + return null; + } + if(level==0){ + return value; + } + Class c = value.getClass(); + if(isNeedlessClone(c)){ + return value; + } + level--; + if(value instanceof Collection){//复制新的集合 + Collection tmp = (Collection)c.newInstance(); + for(Object v:(Collection)value){ + tmp.add(clone(v,level));//深度复制 + } + value = tmp; + } + else if(c.isArray()){//复制新的Array + //首先判断是否为基本数据类型 + if(c.equals(int[].class)){ + int[] old = (int[])value; + value = (int[]) Arrays.copyOf(old, old.length); + } + else if(c.equals(short[].class)){ + short[] old = (short[])value; + value = (short[])Arrays.copyOf(old, old.length); + } + else if(c.equals(char[].class)){ + char[] old = (char[])value; + value = (char[])Arrays.copyOf(old, old.length); + } + else if(c.equals(float[].class)){ + float[] old = (float[])value; + value = (float[])Arrays.copyOf(old, old.length); + } + else if(c.equals(double[].class)){ + double[] old = (double[])value; + value = (double[])Arrays.copyOf(old, old.length); + } + else if(c.equals(long[].class)){ + long[] old = (long[])value; + value = (long[])Arrays.copyOf(old, old.length); + } + else if(c.equals(boolean[].class)){ + boolean[] old = (boolean[])value; + value = (boolean[])Arrays.copyOf(old, old.length); + } + else if(c.equals(byte[].class)){ + byte[] old = (byte[])value; + value = (byte[])Arrays.copyOf(old, old.length); + } + else { + Object[] old = (Object[])value; + Object[] tmp = (Object[])Arrays.copyOf(old, old.length, old.getClass()); + for(int i = 0;i fields = new HashSet(); + while(c!=null&&!c.equals(Object.class)){ + fields.addAll(Arrays.asList(c.getDeclaredFields())); + c = c.getSuperclass(); + } + for(Field field:fields){ + if(!Modifier.isFinal(field.getModifiers())){//仅复制非final字段 + field.setAccessible(true); + field.set(tmp, clone(field.get(value),level));//深度复制 + } + } + value = tmp; + } + return value; + } + + /** + * 浅表复制对象 + * @param value 原始对象 + * @return 复制后的对象,只复制一层 + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static Object clone(Object value) throws IllegalAccessException, InstantiationException { + return clone(value,1); + } + + /** + * 深度复制对象 + * @param value 原始对象 + * @return 复制后的对象 + * @throws IllegalAccessException + * @throws InstantiationException + */ + public static Object deepClone(Object value) throws IllegalAccessException, InstantiationException { + return clone(value,-1); + } + + +//数据:100 深度:10 测试 +//======普通赋值====== +//数据:100 深度:10 +//普通赋值耗时:4~8 +//======克隆工具1====== +//数据:100 深度:10 +//克隆工具1耗时:1272~1987 +//======克隆工具2-1====== +//数据:100 深度:10 +//克隆工具2-1耗时:5~7 +//======克隆工具2-2====== +//数据:100 深度:10 +//克隆工具2-2耗时:15~19 +// +//数据:100 深度:20 测试 +//======普通赋值====== +//数据:100 深度:20 +//普通赋值耗时:6 +//======克隆工具1====== +//数据:100 深度:20 +//克隆工具1耗时:1772 +//======克隆工具2-1====== +//数据:100 深度:20 +//克隆工具2-1耗时:71 +//======克隆工具2-2====== +//数据:100 深度:20 +//克隆工具2-2耗时:216 +// 性能低 +// public static T clone(Object cloneObj) { +// ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); +// ObjectOutputStream out; +// try { +// out = new ObjectOutputStream(byteOut); +// out.writeObject(cloneObj); +// +// ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray()); +// +// ObjectInputStream in = new ObjectInputStream(byteIn); +// +// T retObj = (T) in.readObject(); +// +// return retObj; +// } catch (IOException | ClassNotFoundException e) { +// LOGGER.error("对象" + cloneObj.getClass().getName() + "克隆异常:", e); +// } +// return null; +// } + +}