diff --git a/common/src/main/java/com/jeesite/common/lang/ObjectUtils.java b/common/src/main/java/com/jeesite/common/lang/ObjectUtils.java index 181151c4..7e32fb90 100644 --- a/common/src/main/java/com/jeesite/common/lang/ObjectUtils.java +++ b/common/src/main/java/com/jeesite/common/lang/ObjectUtils.java @@ -14,13 +14,14 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.nustaq.serialization.FSTConfiguration; import org.springframework.beans.BeanUtils; +import org.springframework.core.NamedThreadLocal; import com.jeesite.common.io.IOUtils; /** * 对象操作工具类, 继承org.apache.commons.lang3.ObjectUtils类 * @author ThinkGem - * @version 2014-6-29 + * @version 2018-08-11 */ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils { @@ -212,73 +213,14 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils { } return object; } - -// // Kryo不是线程安全的,所以要建立一个线程变量,每一个线程实例化一次 -// public static final ThreadLocal kryos = new ThreadLocal() { -// @Override -// protected Kryo initialValue() { -// Kryo kryo = new Kryo(); -// // 设置false关闭注册行为, Kryo支持对注册行为,如kryo.register(SomeClazz.class); -// // 这会赋予该Class一个从0开始的编号,但Kryo使用注册行为最大的问题在于, -// // 其不保证同一个Class每一次注册的号码想用,这与注册的顺序有关,也就意味着在不同的机器、 -// // 同一个机器重启前后都有可能拥有不同的编号,这会导致序列化产生问题,所以在分布式项目中,一般关闭注册行为。 -// kryo.setRegistrationRequired(false); -// // 支持循环引用 -// kryo.setReferences(true); -// return kryo; -// }; -// }; -// -// /** -// * Kryo序列化对象 -// * @param object -// * @return -// */ -// public static byte[] serializeKryo(Object object) { -// byte[] bytes = null; -// Output output = null; -// try { -// if (object != null) { -// output = new Output(1024, -1); -// kryos.get().writeClassAndObject(output, object); -// bytes = output.toBytes(); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } finally { -// if (output != null) { -// output.close(); -// } -// } -// return bytes; -// } -// -// /** -// * Kryo反序列化对象 -// * @param bytes -// * @return -// */ -// public static Object unserializeKryo(byte[] bytes) { -// Object object = null; -// Input input = null; -// try { -// if (bytes != null && bytes.length > 0) { -// input = new Input(bytes, 0, bytes.length); -// object = kryos.get().readClassAndObject(input); -// } -// } catch (Exception e) { -// e.printStackTrace(); -// } finally { -// if (input != null) { -// input.close(); -// } -// } -// return object; -// } // FST序列化配置对象 - private static FSTConfiguration fst = FSTConfiguration.createDefaultConfiguration(); - + private static ThreadLocal fst = new NamedThreadLocal("FSTConfiguration") { + public FSTConfiguration initialValue() { + return FSTConfiguration.createDefaultConfiguration(); + } + }; + /** * FST 序列化对象 * @param object @@ -289,7 +231,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils { return null; } long beginTime = System.currentTimeMillis(); - byte[] bytes = fst.asByteArray(object); + byte[] bytes = fst.get().asByteArray(object); long totalTime = System.currentTimeMillis() - beginTime; if (totalTime > 3000){ System.out.println("Fst serialize time: " + TimeUtils.formatDateAgo(totalTime)); @@ -307,7 +249,7 @@ public class ObjectUtils extends org.apache.commons.lang3.ObjectUtils { return null; } long beginTime = System.currentTimeMillis(); - Object object = fst.asObject(bytes); + Object object = fst.get().asObject(bytes); long totalTime = System.currentTimeMillis() - beginTime; if (totalTime > 3000){ System.out.println("Fst unserialize time: " + TimeUtils.formatDateAgo(totalTime)); diff --git a/common/src/main/java/com/jeesite/common/utils/excel/ExcelExport.java b/common/src/main/java/com/jeesite/common/utils/excel/ExcelExport.java index 2f83f28e..5ff088d8 100644 --- a/common/src/main/java/com/jeesite/common/utils/excel/ExcelExport.java +++ b/common/src/main/java/com/jeesite/common/utils/excel/ExcelExport.java @@ -3,6 +3,7 @@ */ package com.jeesite.common.utils.excel; +import java.io.Closeable; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; @@ -13,8 +14,10 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.http.HttpServletResponse; @@ -36,6 +39,7 @@ import org.slf4j.LoggerFactory; import com.fasterxml.jackson.annotation.JsonFormat; import com.jeesite.common.codec.EncodeUtils; import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.SetUtils; import com.jeesite.common.lang.ObjectUtils; import com.jeesite.common.lang.StringUtils; import com.jeesite.common.reflect.ReflectUtils; @@ -47,9 +51,9 @@ import com.jeesite.common.utils.excel.annotation.ExcelFields; /** * 导出Excel文件(导出“XLSX”格式,支持大数据量导出 @see org.apache.poi.ss.SpreadsheetVersion) * @author ThinkGem - * @version 2013-04-21 + * @version 2018-08-11 */ -public class ExcelExport { +public class ExcelExport implements Closeable{ private static Logger log = LoggerFactory.getLogger(ExcelExport.class); @@ -76,7 +80,12 @@ public class ExcelExport { /** * 注解列表(Object[]{ ExcelField, Field/Method }) */ - List annotationList; + private List annotationList; + + /** + * 用于清理缓存 + */ + private Set> fieldTypes = SetUtils.newHashSet(); /** * 构造函数 @@ -431,6 +440,7 @@ public class ExcelExport { if(val == null){ cell.setCellValue(""); }else if(fieldType != Class.class){ + fieldTypes.add(fieldType); // 先存起来,方便完成后清理缓存 cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val)); try{ defaultDataFormat = (String)fieldType.getMethod("getDataFormat").invoke(null); @@ -456,8 +466,11 @@ public class ExcelExport { cell.setCellValue((Date) val); defaultDataFormat = "yyyy-MM-dd HH:mm"; }else { - cell.setCellValue((String)Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), - "fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val)); + // 如果没有指定 fieldType,切自行根据类型查找相应的转换类(com.jeesite.common.utils.excel.fieldtype.值的类名+Type) + Class fieldType2 = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), + "fieldtype."+val.getClass().getSimpleName()+"Type")); + fieldTypes.add(fieldType2); // 先存起来,方便完成后清理缓存 + cell.setCellValue((String)fieldType2.getMethod("setValue", Object.class).invoke(null, val)); } } // if (val != null){ @@ -574,12 +587,31 @@ public class ExcelExport { /** * 清理临时文件 + * @deprecated see close() */ public ExcelExport dispose(){ + try { + this.close(); + } catch (Exception e) { + e.printStackTrace(); + } + return this; + } + + @Override + public void close() { if (wb instanceof SXSSFWorkbook){ ((SXSSFWorkbook)wb).dispose(); } - return this; + Iterator> it = fieldTypes.iterator(); + while(it.hasNext()){ + Class clazz = it.next(); + try { + clazz.getMethod("clearCache").invoke(null); + } catch (Exception e) { + // 报错忽略,有可能没实现此方法 + } + } } // /** diff --git a/common/src/main/java/com/jeesite/common/utils/excel/ExcelImport.java b/common/src/main/java/com/jeesite/common/utils/excel/ExcelImport.java index bb2678f9..ed299cc3 100644 --- a/common/src/main/java/com/jeesite/common/utils/excel/ExcelImport.java +++ b/common/src/main/java/com/jeesite/common/utils/excel/ExcelImport.java @@ -3,6 +3,7 @@ */ package com.jeesite.common.utils.excel; +import java.io.Closeable; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -15,6 +16,7 @@ import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; @@ -34,6 +36,7 @@ import org.springframework.web.multipart.MultipartFile; import com.jeesite.common.callback.MethodCallback; import com.jeesite.common.collect.ListUtils; +import com.jeesite.common.collect.SetUtils; import com.jeesite.common.lang.DateUtils; import com.jeesite.common.lang.ObjectUtils; import com.jeesite.common.lang.StringUtils; @@ -45,9 +48,9 @@ import com.jeesite.common.utils.excel.annotation.ExcelFields; /** * 导入Excel文件(支持“XLS”和“XLSX”格式) * @author ThinkGem - * @version 2014-8-19 + * @version 2018-08-11 */ -public class ExcelImport { +public class ExcelImport implements Closeable { private static Logger log = LoggerFactory.getLogger(ExcelImport.class); @@ -66,6 +69,11 @@ public class ExcelImport { */ private int headerNum; + /** + * 用于清理缓存 + */ + private Set> fieldTypes = SetUtils.newHashSet(); + /** * 构造函数 * @param path 导入文件对象,读取第一个工作表 @@ -418,6 +426,7 @@ public class ExcelImport { try { if (StringUtils.isNotBlank(ef.attrName())){ if (ef.fieldType() != Class.class){ + fieldTypes.add(ef.fieldType()); // 先存起来,方便完成后清理缓存 val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val); } }else{ @@ -445,10 +454,14 @@ public class ExcelImport { } }else{ if (ef.fieldType() != Class.class){ + fieldTypes.add(ef.fieldType()); // 先存起来,方便完成后清理缓存 val = ef.fieldType().getMethod("getValue", String.class).invoke(null, val.toString()); }else{ - val = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), - "fieldtype."+valType.getSimpleName()+"Type")).getMethod("getValue", String.class).invoke(null, val.toString()); + // 如果没有指定 fieldType,切自行根据类型查找相应的转换类(com.jeesite.common.utils.excel.fieldtype.值的类名+Type) + Class fieldType2 = Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), + "fieldtype."+valType.getSimpleName()+"Type")); + fieldTypes.add(fieldType2); // 先存起来,方便完成后清理缓存 + val = fieldType2.getMethod("getValue", String.class).invoke(null, val.toString()); } } } @@ -481,6 +494,19 @@ public class ExcelImport { } return dataList; } + + @Override + public void close() { + Iterator> it = fieldTypes.iterator(); + while(it.hasNext()){ + Class clazz = it.next(); + try { + clazz.getMethod("clearCache").invoke(null); + } catch (Exception e) { + // 报错忽略,有可能没实现此方法 + } + } + } // /** // * 导入测试 diff --git a/common/src/main/java/com/jeesite/common/utils/excel/fieldtype/MoneyType.java b/common/src/main/java/com/jeesite/common/utils/excel/fieldtype/MoneyType.java index 3da5e76b..bafde986 100644 --- a/common/src/main/java/com/jeesite/common/utils/excel/fieldtype/MoneyType.java +++ b/common/src/main/java/com/jeesite/common/utils/excel/fieldtype/MoneyType.java @@ -37,4 +37,11 @@ public class MoneyType { return "0.00"; } + /** + * 清理缓存 + */ + public static void clearCache(){ + + } + } diff --git a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/AreaType.java b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/AreaType.java index 1b4269f9..f04172ef 100644 --- a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/AreaType.java +++ b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/AreaType.java @@ -5,6 +5,8 @@ package com.jeesite.common.utils.excel.fieldtype; import java.util.List; +import org.springframework.core.NamedThreadLocal; + import com.jeesite.common.lang.StringUtils; import com.jeesite.modules.sys.entity.Area; import com.jeesite.modules.sys.utils.AreaUtils; @@ -12,12 +14,12 @@ import com.jeesite.modules.sys.utils.AreaUtils; /** * 字段类型转换 * @author ThinkGem - * @version 2013-03-10 + * @version 2018-08-11 * @example fieldType = AreaType.class */ public class AreaType { - private static ThreadLocal> cache = new ThreadLocal<>(); + private static ThreadLocal> cache = new NamedThreadLocal<>("AreaType"); /** * 获取对象值(导入) @@ -45,4 +47,12 @@ public class AreaType { } return ""; } + + /** + * 清理缓存 + */ + public static void clearCache(){ + cache.remove(); + } + } diff --git a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/CompanyType.java b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/CompanyType.java index b5825bd2..157cbc3b 100644 --- a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/CompanyType.java +++ b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/CompanyType.java @@ -5,6 +5,8 @@ package com.jeesite.common.utils.excel.fieldtype; import java.util.List; +import org.springframework.core.NamedThreadLocal; + import com.jeesite.common.lang.StringUtils; import com.jeesite.modules.sys.entity.Company; import com.jeesite.modules.sys.utils.EmpUtils; @@ -12,12 +14,12 @@ import com.jeesite.modules.sys.utils.EmpUtils; /** * 字段类型转换 * @author ThinkGem - * @version 2015-03-24 + * @version 2018-08-11 * @example fieldType = CompanyType.class */ public class CompanyType { - private static ThreadLocal> cache = new ThreadLocal<>(); + private static ThreadLocal> cache = new NamedThreadLocal<>("CompanyType"); /** * 获取对象值(导入) @@ -45,4 +47,11 @@ public class CompanyType { } return ""; } + + /** + * 清理缓存 + */ + public static void clearCache(){ + cache.remove(); + } } diff --git a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/OfficeType.java b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/OfficeType.java index d0d1bc0c..b7fc3413 100644 --- a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/OfficeType.java +++ b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/OfficeType.java @@ -5,6 +5,8 @@ package com.jeesite.common.utils.excel.fieldtype; import java.util.List; +import org.springframework.core.NamedThreadLocal; + import com.jeesite.common.lang.StringUtils; import com.jeesite.modules.sys.entity.Office; import com.jeesite.modules.sys.utils.EmpUtils; @@ -12,12 +14,12 @@ import com.jeesite.modules.sys.utils.EmpUtils; /** * 字段类型转换 * @author ThinkGem - * @version 2013-03-10 + * @version 2018-08-11 * @example fieldType = OfficeType.class */ public class OfficeType { - private static ThreadLocal> cache = new ThreadLocal<>(); + private static ThreadLocal> cache = new NamedThreadLocal<>("OfficeType"); /** * 获取对象值(导入) @@ -45,4 +47,11 @@ public class OfficeType { } return ""; } + + /** + * 清理缓存 + */ + public static void clearCache(){ + cache.remove(); + } } diff --git a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/PostListType.java b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/PostListType.java index 626fd05f..e08e7c72 100644 --- a/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/PostListType.java +++ b/modules/core/src/main/java/com/jeesite/common/utils/excel/fieldtype/PostListType.java @@ -5,6 +5,8 @@ package com.jeesite.common.utils.excel.fieldtype; import java.util.List; +import org.springframework.core.NamedThreadLocal; + import com.jeesite.common.collect.ListUtils; import com.jeesite.common.lang.StringUtils; import com.jeesite.common.utils.SpringUtils; @@ -14,13 +16,13 @@ import com.jeesite.modules.sys.service.PostService; /** * 字段类型转换 * @author ThinkGem - * @version 2015-03-24 + * @version 2018-08-11 * @example fieldType = PostListType.class */ public class PostListType { private static PostService postService = SpringUtils.getBean(PostService.class); - private static ThreadLocal> cache = new ThreadLocal<>(); + private static ThreadLocal> cache = new NamedThreadLocal<>("PostListType"); /** * 获取对象值(导入) @@ -53,4 +55,11 @@ public class PostListType { } return ""; } + + /** + * 清理缓存 + */ + public static void clearCache(){ + cache.remove(); + } } diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/interceptor/LogInterceptor.java b/modules/core/src/main/java/com/jeesite/modules/sys/interceptor/LogInterceptor.java index c97d5bb3..93734af7 100644 --- a/modules/core/src/main/java/com/jeesite/modules/sys/interceptor/LogInterceptor.java +++ b/modules/core/src/main/java/com/jeesite/modules/sys/interceptor/LogInterceptor.java @@ -22,12 +22,12 @@ import com.jeesite.modules.sys.utils.UserUtils; /** * 日志拦截器 * @author ThinkGem - * @version 2014-8-19 + * @version 2018-08-11 */ public class LogInterceptor extends BaseService implements HandlerInterceptor { private static final ThreadLocal startTimeThreadLocal = - new NamedThreadLocal("ThreadLocal StartTime"); + new NamedThreadLocal("LogInterceptor StartTime"); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/service/EmpUserService.java b/modules/core/src/main/java/com/jeesite/modules/sys/service/EmpUserService.java index a2233322..8c023be9 100644 --- a/modules/core/src/main/java/com/jeesite/modules/sys/service/EmpUserService.java +++ b/modules/core/src/main/java/com/jeesite/modules/sys/service/EmpUserService.java @@ -116,8 +116,7 @@ public class EmpUserService extends CrudService { int successNum = 0; int failureNum = 0; StringBuilder successMsg = new StringBuilder(); StringBuilder failureMsg = new StringBuilder(); - try { - ExcelImport ei = new ExcelImport(file, 2, 0); + try(ExcelImport ei = new ExcelImport(file, 2, 0)){ List list = ei.getDataList(EmpUser.class); for (EmpUser user : list) { try{ diff --git a/modules/core/src/main/java/com/jeesite/modules/sys/web/user/EmpUserController.java b/modules/core/src/main/java/com/jeesite/modules/sys/web/user/EmpUserController.java index 9785833c..da832d53 100644 --- a/modules/core/src/main/java/com/jeesite/modules/sys/web/user/EmpUserController.java +++ b/modules/core/src/main/java/com/jeesite/modules/sys/web/user/EmpUserController.java @@ -177,8 +177,9 @@ public class EmpUserController extends BaseController { } List list = empUserService.findList(empUser); String fileName = "用户数据" + DateUtils.getDate("yyyyMMddHHmmss") + ".xlsx"; - new ExcelExport("用户数据", EmpUser.class).setDataList(list) - .write(response, fileName).dispose(); + try(ExcelExport ee = new ExcelExport("用户数据", EmpUser.class)){ + ee.setDataList(list).write(response, fileName); + } } /** @@ -196,8 +197,9 @@ public class EmpUserController extends BaseController { } List list = ListUtils.newArrayList(empUser); String fileName = "用户数据模板.xlsx"; - new ExcelExport("用户数据", EmpUser.class, Type.IMPORT).setDataList(list) - .write(response, fileName).dispose(); + try(ExcelExport ee = new ExcelExport("用户数据", EmpUser.class, Type.IMPORT)){ + ee.setDataList(list).write(response, fileName); + } } /** diff --git a/modules/core/src/main/resources/views/modules/sys/sysDesktop.html b/modules/core/src/main/resources/views/modules/sys/sysDesktop.html index f903c61a..a51eec5b 100644 --- a/modules/core/src/main/resources/views/modules/sys/sysDesktop.html +++ b/modules/core/src/main/resources/views/modules/sys/sysDesktop.html @@ -60,7 +60,7 @@
-
+

月度报告