package zxc.util.ieport; import java.util.List; import java.util.Map; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.util.CollectionUtils; import zxc.exceptions.BaseRuntimeException; import zxc.model.support.BaseBean; import zxc.model.support.FileBaseBean; import zxc.model.support.IeudBean; import zxc.util.ieport.poi.POIExcelFactory; import zxc.utils.Page; /** * 在测试本服务时出现了不少问题,切点的定义总是不能找到目标方法.当前初的设想是这样的,因为底层有一个查询方法提供了一个较宽 * 的查询区域,其它一些较窄的方法可以调用它,那么我觉得将这个服务绑定到最底层的方法调用后这样就不必在每一个需要此服务的方法 * 前打NeedExprot,或者去写一个复杂切点表达式,但是测试了很长时间仍不能成功,表现出来的现象是,有个别方法可以,而大部分方法 * 不能被成功的绑定此服务,最后发现好象有这样一个规律,如果一个方法被本类中的其它方法调用,则被调用的方法将不会应用服务,具体是 * 不是这样我也不确定,其实我联想到事务的控制,这个事务控制服务是不是也这样一种情况呢?即最外层的方法会应用服务呢?因为这也与事务 * 表现有些相似,即具有某种服务的对象,如果它具有同种服务的方法调用,则内面的方法的服务就会被屏蔽掉,这个结论还需要进一步验证 * * * @author KHT * */ @Aspect public class ExportService { public static final Integer DEFAULT_MAX_COUNT_ONE_TIME = 50; public static final Integer DEFAULT_MAX_EXPORT_TIMES = 50; public static final Integer EXCEL_SUPPORT_MAX_COUNT = 60000; private Integer maxCountOneTime; @SuppressWarnings("unused") @Pointcut(value = "@annotation(zxc.util.ieport.NeedExport)") private void needExport() { } //@AfterReturning(value = "needExport() && args(model,..)", returning = "rowset") public void processExport(BaseBean model, List<Map<String, Object>> rowset) { IeudBean ieudBean = ((FileBaseBean) model).getIeudBean(); ieudBean.setExportData(rowset); POIExcelFactory.getFactory().processExcelExport((FileBaseBean) model); } public Integer getMaxCountOneTime() { if (maxCountOneTime == null) { maxCountOneTime = DEFAULT_MAX_COUNT_ONE_TIME; } return maxCountOneTime; } public void setMaxCountOneTime(Integer maxCountOneTime) { this.maxCountOneTime = maxCountOneTime; } @Around("needExport()") public Object processExport(ProceedingJoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); FileBaseBean model = (FileBaseBean) args[0]; IeudBean ieudBean = model.getIeudBean(); List<?> list = null; try { //需要导出 if (ieudBean.getExport() != null && ieudBean.getExport()) { //这里返回的list没有太大的意义,为了节省内存空间,只返回了最后页的数据 list = exportData(joinPoint, args, model, ieudBean); } else { list = (List<?>) joinPoint.proceed(args); } } catch (Throwable e) { throw new BaseRuntimeException("获取导入导出实体失败", e); } return list; } //此方法完全是处理导出 private List<?> exportData(ProceedingJoinPoint joinPoint, Object[] args, BaseBean model, IeudBean ieudBean) throws Throwable { List<?> list = null; //处理一次性导出 if (ieudBean.getOneTimeExport()) { list = (List<?>) joinPoint.proceed(args); ieudBean.setExportData(list); POIExcelFactory.getFactory().processExcelExport((FileBaseBean) model); System.err.println("一次性导出..."); } else {//处理分批导出 Integer maxCount = ieudBean.getMaxCountOneTime(); if (maxCount == null || maxCount <= 0) { maxCount = this.getMaxCountOneTime(); } if (model.getPage() == null) { model.setPage(new Page()); } model.getPage().setLimit(maxCount); Integer maxTimes = EXCEL_SUPPORT_MAX_COUNT / maxCount; Integer currentTimes = 0; boolean isExit = false; do { model.getPage().setStart(currentTimes * maxCount); currentTimes++; System.err.println("分批导出:" + currentTimes); list = (List<?>) joinPoint.proceed(args); ieudBean.setExportData(list); if (CollectionUtils.isEmpty(list) || list.size() < maxCount || currentTimes >= maxTimes) { //设置已经导出完成的标记,以便完成导出的结束工作 ieudBean.setExportCompleted(true); isExit = true;//退出循环 } POIExcelFactory.getFactory().processExcelExport((FileBaseBean) model); } while (!isExit); } return list; } }