定时任务-quartz的使用,实现可页面化管理

2023-10-27

定时任务-quartz的使用,实现可页面化管理
使用spring+quartz实现定时任务的页面化管理。主要特点:
1.时间表达式等信息配置在数据库中,从而实现页面化管理。
2.可以手动执行或者停止单个任务,也可以使一个任务加入或者移出自动运行列表。

下面开始介绍用法,在这之前先说明框架的版本。spring3.2.4+quartz1.6.0
一.配置文件
只需要在spring的配置文件中加入:
<bean id="scheduler"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
	</bean>
	<bean id="jobManager"  class="com.temobi.quartz.JobManager">  
	</bean> 

说明:scheduler对象是spring管理定时任务的对象。
jobManager是我们自定义加载定时任务列表的对象,此对象加载所有任务列表后,将他们加入到自动运行列表。
二.jobManager代码:
public class JobManager implements InitializingBean  {
	private static final Log log = LogFactory.getLog(JobManager.class);
	@Autowired
	TaskJobService taskJobService;
	@Autowired
	QuartzManager quartzManager;
	@Override
	public void afterPropertiesSet() throws Exception {
		loadAllJob();
	}
	private void loadAllJob(){
		List<TaskJob> list =taskJobService.getTaskList();
		quartzManager.enableCronSchedule(list);
	}
	
}


说明:
1.实现spring中InitializingBean接口,并覆盖afterPropertiesSet方法,则该方法会在应用启动的时候而且其他servlet执行完成之后执行,此处用来加载所有定时任务,并加入定时任务自动运行列表。
2.quartzManager是我们自定义的定时任务管理类,用来实现我们文章开头说的功能。
三.QuartzManager代码
@Controller
public class QuartzManager {
	@Autowired
	Scheduler scheduler;
	
	private static final Log log = LogFactory.getLog(QuartzManager.class);
	public void enableCronSchedule(List<TaskJob> list) {
		for(TaskJob task : list){
			SchedulingJob job = new SchedulingJob();
			job.setJobId(task.getId());
			job.setJobName(task.getJobName());
			//job.setMemos(task.getNote());
			job.setCronExpression(task.getJobCronExpression());
			try{
			String  className=	task.getJobClass().trim();
				Class clazz = Class.forName(className);
				job.setStateFulljobExecuteClass(clazz);
			}catch(Exception e){
				e.printStackTrace();
				continue;
			}
			JobDataMap paramsMap = new JobDataMap();
			paramsMap.put("jobName", task.getJobName());

			if(task.getParamsKey1()!=null && task.getParamsValue1()!=null){
				paramsMap.put(task.getParamsKey1(), task.getParamsValue1());
			}
			if(task.getParamsKey2()!=null && task.getParamsValue2()!=null){
				paramsMap.put(task.getParamsKey2(), task.getParamsValue2());
			}
			if(task.getParamsKey3()!=null && task.getParamsValue3()!=null){
				paramsMap.put(task.getParamsKey3(), task.getParamsValue3());
			}
			enableCronSchedule(job, paramsMap, true);
			
			log.info("系统结束初始化任务:"+task.getId()+":"+task.getJobName()+":"+task.getJobId());
		}
	}
	/**
	 * 启动一个自定义的job
	 * 
	 * @param schedulingJob
	 *            自定义的job
	 * @param paramsMap
	 *            传递给job执行的数据
	 * @param isStateFull
	 *            是否是一个同步定时任务,true:同步,false:异步
	 * @return 成功则返回true,否则返回false
	 */
	public boolean enableCronSchedule(SchedulingJob schedulingJob, JobDataMap paramsMap, boolean isStateFull) {
		if (schedulingJob == null) {
			return false;
		}
		try {
			//scheduler = (Scheduler) ApplicationHelper.getBean("scheduler");
			CronTrigger trigger = (CronTrigger) scheduler.getTrigger(schedulingJob.getTriggerName(),
					schedulingJob.getJobGroup());
			if (null == trigger) {// 如果不存在该trigger则创建一个
				JobDetail jobDetail = null;
				if (isStateFull) {
					jobDetail = new JobDetail(schedulingJob.getJobId(), schedulingJob.getJobGroup(),
							schedulingJob.getStateFulljobExecuteClass());
				} else {
					jobDetail = new JobDetail(schedulingJob.getJobId(), schedulingJob.getJobGroup(),
							schedulingJob.getJobExecuteClass());
				}
				jobDetail.setJobDataMap(paramsMap);
				trigger = new CronTrigger(schedulingJob.getTriggerName(), schedulingJob.getJobGroup(),
						schedulingJob.getCronExpression());
				scheduler.scheduleJob(jobDetail, trigger);
			} else {
				// Trigger已存在,那么更新相应的定时设置
				trigger.setCronExpression(schedulingJob.getCronExpression());
				scheduler.rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 禁用一个job
	 * 
	 * @param jobId
	 *            需要被禁用的job的ID
	 * @param jobGroupId
	 *            需要被警用的jobGroupId
	 * @return 成功则返回true,否则返回false
	 */
	public boolean disableSchedule(String jobId) {
		if (jobId.equals("")) {
			return false;
		}
		try {
			String jobGroupId="DEFAULT";
			Trigger trigger = getJobTrigger(jobId, jobGroupId);
			if (null != trigger) {
				scheduler.deleteJob(jobId, jobGroupId);
			}
		} catch (SchedulerException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 得到job的详细信息
	 * 
	 * @param jobId
	 *            job的ID
	 * @param jobGroupId
	 *            job的组ID
	 * @return job的详细信息,如果job不存在则返回null
	 */
	public JobDetail getJobDetail(String jobId, String jobGroupId) {
		if (jobId.equals("") || jobGroupId.equals("") || null == jobId || jobGroupId == null) {
			return null;
		}
		try {
			return scheduler.getJobDetail(jobId, jobGroupId);
		} catch (SchedulerException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 得到job对应的Trigger
	 * 
	 * @param jobId
	 *            job的ID
	 * @param jobGroupId
	 *            job的组ID
	 * @return job的Trigger,如果Trigger不存在则返回null
	 */
	public Trigger getJobTrigger(String jobId, String jobGroupId) {
		if (jobId.equals("") || jobGroupId.equals("") || null == jobId || jobGroupId == null) {
			return null;
		}
		try {
			return scheduler.getTrigger(jobId + "Trigger", jobGroupId);
		} catch (SchedulerException e) {
			e.printStackTrace();
			return null;
		}
	}

}


说明:
1.主要方法有三个,启动一个任务,禁用一个任务,启动多个任务。启动即加入自动运行列表,禁用即移出自动运行列表。
2.TaskJob是一个任务对象,和数据库表结构相对应,后面给出数据库设计。
3.程序中有类似,
paramsMap.put(task.getParamsKey1(), task.getParamsValue1());
这样的代码,意思是假如你:如果你在数据库的ParamsKey1值为"username",ParamsValue1的值为"zhangsang".那么你在具体的job中给定变量名为"username"的变量并给出set/get方法,就可以得到值"zhangsang",此功能适用于给定时任务配置固定参数,并且参数名字随便你定。我们这里给了三个备用的,你也可以扩展,步骤就是数据库加一个字段,在上面的程序中paramsMap放入这个字段,当然你也可以不用参数。你数据库没有配置任何值,表示该定时任务没有固定参数。
4.SchedulingJob是一个定时任务执行参数的bean。即 将Taskjob对象的值经过处理转换成SchedulingJob对象,然后用SchedulingJob对象的值调用定时任务的API。
SchedulingJob对象主要做的事就是,TriggerName和JobGroup分别给出默认值。根据className生成StateFulljobExecuteClass的Class对象。
四。SchedulingJob代码:
public class SchedulingJob {
	public static final int JS_ENABLED = 0; // 任务启用状态
    public static final int JS_DISABLED = 1; // 任务禁用状态
    public static final int JS_DELETE = 2; // 任务已删除状态

    private String jobId; // 任务的Id,一般为所定义Bean的ID
    private String jobName; // 任务的描述
    private String jobGroup; // 任务所属组的名称
    private int jobStatus; // 任务的状态,0:启用;1:禁用;2:已删除
    private String cronExpression; // 定时任务运行时间表达式
    private String memos; // 任务描述
    private Class<?> stateFulljobExecuteClass;//同步的执行类,需要从StatefulMethodInvokingJob继承
    private Class<?> jobExecuteClass;//异步的执行类,需要从MethodInvokingJob继承
      /**
       * 得到该job的Trigger名字
       * @return
       */
     public String getTriggerName() {
            return this.getJobId() + "Trigger";
     }
	public String getJobId() {
		return jobId;
	}
	public void setJobId(String jobId) {
		this.jobId = jobId;
	}
	public String getJobName() {
		return jobName;
	}
	public void setJobName(String jobName) {
		this.jobName = jobName;
	}
	public String getJobGroup() {
		if(jobGroup==null){
			jobGroup = Scheduler.DEFAULT_GROUP;
		}
		return jobGroup;
	}
	public void setJobGroup(String jobGroup) {
		this.jobGroup = jobGroup;
	}
	public int getJobStatus() {
		return jobStatus;
	}
	public void setJobStatus(int jobStatus) {
		this.jobStatus = jobStatus;
	}
	public String getCronExpression() {
		return cronExpression;
	}
	public void setCronExpression(String cronExpression) {
		this.cronExpression = cronExpression;
	}
	public String getMemos() {
		return memos;
	}
	public void setMemos(String memos) {
		this.memos = memos;
	}
	public Class<?> getStateFulljobExecuteClass() {
		return stateFulljobExecuteClass;
	}
	public void setStateFulljobExecuteClass(Class<?> stateFulljobExecuteClass) {
		this.stateFulljobExecuteClass = stateFulljobExecuteClass;
	}
	public Class<?> getJobExecuteClass() {
		return jobExecuteClass;
	}
	public void setJobExecuteClass(Class<?> jobExecuteClass) {
		this.jobExecuteClass = jobExecuteClass;
	}
	public static int getJS_ENABLED() {
		return JS_ENABLED;
	}
	public static int getJS_DISABLED() {
		return JS_DISABLED;
	}
	public static int getJS_DELETE() {
		return JS_DELETE;
	}

}

五。具体JOB实现
只要继承QuartzJobBean类,覆盖executeInternal方法即可。在job中可能通过get方法的方式得到jobDetail对象中JobDataMap(详见QuartzManager类)中同名参数值。示例代码。
@Controller
public class ContentJob extends QuartzJobBean{
	@Autowired
	TaskJobService taskJobService;
	private String  beginDate;
	private String  endDate;
	
	/**
	 * 手动执行任务
	 * @param request
	 */
	@RequestMapping("/contentJobManual.do")
	public void manual(HttpServletRequest request) {
		String startDate=request.getParameter("startDate");
		String endDate=request.getParameter("endDate");
		TaskJobService taskJobService = (TaskJobService) ApplicationHelper.getBean("taskJobService");
		Map<String, String> param = new HashMap<String, String>();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String today=sdf.format(new Date());
		if(StringUtils.isEmpty(startDate)){
			param.put("beginDate", today); 
		}else{
			param.put("beginDate", startDate); 
		}
		if(StringUtils.isEmpty(endDate)){
			param.put("endDate", today); 
		}else{
			param.put("endDate", endDate); 
		}
		taskJobService.callStatisticContent(param);
	}
	
	@Override
	public void executeInternal(JobExecutionContext context) {
		TaskJobService taskJobService = (TaskJobService) ApplicationHelper.getBean("taskJobService");
		Map<String, String> param = new HashMap<String, String>();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		String today=sdf.format(new Date());
		if(StringUtils.isEmpty(beginDate)){
			param.put("beginDate", today); 
		}else{
			param.put("beginDate", beginDate); 
		}
		if(StringUtils.isEmpty(endDate)){
			param.put("endDate", today); 
		}else{
			param.put("endDate", endDate); 
		}
		taskJobService.callStatisticContent(param);
	}
	
	public String getBeginDate() {
		return beginDate;
	}

	public void setBeginDate(String beginDate) {
		this.beginDate = beginDate;
	}

	public String getEndDate() {
		return endDate;
	}
	public void setEndDate(String endDate) {
		this.endDate = endDate;
	}

六。手动执行一个任务。可以将该job类声明成一个@Controller。另外写一个方法如上例中的manual方法。
扩展:目前还不能将自动运行的方法和手动执行的方法(即executeInternal方法和manual方法)写成一个。因为自动运行的方法不是一个action类,它不在web环境中,是通过反射实现的。如果把executeInternal这个方法强行配置成具有web功能的方法(即类上面加@Controller,方法上面加@RequestMapping("/contentJobManual.do"))也是不行的,因为该方法没有HttpServletRequest对象,获取不了参数。除非你的定时任务没有参数。当然你也不能修改该方法的参数类型,因为他是覆盖QuartzJobBean的方法。
七。数据库设计。
ID	VARCHAR2(60)	N				
JOB_CLASS	VARCHAR2(255)	N			
JOB_NAME	VARCHAR2(60)	N			
JOB_CRON_EXPRESSION	VARCHAR2(60)	N		
JOB_SERVICE_BEAN	VARCHAR2(60)	Y			
PARAMS_KEY1	VARCHAR2(60)	Y			
PARAMS_VALUE1	VARCHAR2(60)	Y			
PARAMS_KEY2	VARCHAR2(60)	Y			
PARAMS_VALUE2	VARCHAR2(60)	Y			
PARAMS_KEY3	VARCHAR2(60)	Y			
PARAMS_VALUE3	VARCHAR2(60)	Y			
NOTE	VARCHAR2(255)	Y			
JOB_STATUS	VARCHAR2(1)	Y			
UPDATETIME	DATE	Y			
JOB_AUTORUN	VARCHAR2(1)	Y
JOB_GROUP	VARCHAR2(60)	Y			

说明:JOB_STATUS表示是否有效任务,JOB_AUTORUN表示是否自动运行,JOB_SERVICE_BEAN表示手动执行的请求URL,JOB_CLASS表示JOB类的全路径,JOB_GROUP表示任务属于哪个组,方便对任务的分组管理(批量启动,禁止等),区别于quartz的API所要求的同名参数,其实也可以把这个值传给API。其它字段比较好理解。该表对应的bean是taskjob。
八。页面管理。
主要功能是将一个任务加入或者移出自动运行队列(通过quartzManager对象)。和任务的增删查改。示例代码如下:
@Controller
public class TaskJobAction{
	private static final Log log = LogFactory.getLog(TaskJobAction.class);
	@Autowired
	TaskJobService taskJobService;
	@Autowired
	QuartzManager quartzManager;
	
	@RequestMapping("/enableTask.do")
	public void enableTask(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String parameterStr="";
		parameterStr = IOUtils.toString(request.getInputStream(), InputConstant.CHAR_SET);
		parameterStr = StringUtils.trim(parameterStr);
		parameterStr =URLDecoder.decode(parameterStr,"utf-8");
		Map<String, String> p = JsonUtil.getParameterMap(parameterStr);
		String id=p.get("id");
		if(!StringUtils.isEmpty(id)){
			TaskJob task=taskJobService.getTaskById(id);
			List<TaskJob> list=new ArrayList<TaskJob>();
			list.add(task);
			quartzManager.enableCronSchedule(list);
			
			task.setJobEnabled("Y");
			taskJobService.update(task);//将任务设置成自动运行状态
		}
			
	}
	@RequestMapping("/disableTask.do")
	public void disableTask(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String parameterStr="";
		parameterStr = IOUtils.toString(request.getInputStream(), InputConstant.CHAR_SET);
		parameterStr = StringUtils.trim(parameterStr);
		parameterStr =URLDecoder.decode(parameterStr,"utf-8");
		Map<String, String> p = JsonUtil.getParameterMap(parameterStr);
		String id=p.get("id");
		if(!StringUtils.isEmpty(id)){
			TaskJob task=taskJobService.getTaskById(id);
			quartzManager.disableSchedule(task.getJobId());
			
			task.setJobEnabled("N");
			taskJobService.update(task);//将任务设置成非运行状态
		}
			
	}
	@RequestMapping("/add.do")
	public void add(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String parameterStr="";
			parameterStr = IOUtils.toString(request.getInputStream(), InputConstant.CHAR_SET);
			parameterStr = StringUtils.trim(parameterStr);
			Map<String, String> p = JsonUtil.getParameterMap(parameterStr);
			String jobjson=p.get("jobjson");
			jobjson=URLDecoder.decode(jobjson,"utf-8");
			TaskJob task=JsonUtil.toObject(jobjson, TaskJob.class);
			String jobName=URLDecoder.decode(task.getJobName(),"utf-8");
			task.setJobName(jobName);
			if(!StringUtils.isEmpty(jobjson)){
				taskJobService.insert(task);
			}
			
	}
	
	@RequestMapping("/update.do")
	public void update(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String parameterStr="";
			parameterStr = IOUtils.toString(request.getInputStream(), InputConstant.CHAR_SET);
			parameterStr = StringUtils.trim(parameterStr);
			Map<String, String> p = JsonUtil.getParameterMap(parameterStr);
			String jobjson=p.get("jobjson");
			jobjson=URLDecoder.decode(jobjson,"utf-8");
			TaskJob task=JsonUtil.toObject(jobjson, TaskJob.class);
			String jobName=URLDecoder.decode(task.getJobName(),"utf-8");
			task.setJobName(jobName);
			if(!StringUtils.isEmpty(jobjson)){
				taskJobService.update(task);
			}
			
	}
	
	@RequestMapping("/delete.do")
	public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String parameterStr="";
			parameterStr = IOUtils.toString(request.getInputStream(), InputConstant.CHAR_SET);
			parameterStr = StringUtils.trim(parameterStr);
			parameterStr =URLDecoder.decode(parameterStr,"utf-8");
			Map<String, String> p = JsonUtil.getParameterMap(parameterStr);
			String idStr=p.get("idStr");
			if(!StringUtils.isEmpty(idStr)){
				taskJobService.delete(idStr);
			}
			
	}
	@ResponseBody
	@RequestMapping("/taskList.do")
	public RecordResultBean list(HttpServletRequest request, HttpServletResponse response,@RequestParam("pageSize") int pageSize,
			@RequestParam("startIndex") int startIndex) throws IOException {
		int pageNum=startIndex/pageSize+1;
		String startDate=request.getParameter("startDate");
		String endDate=request.getParameter("endDate");
		String jobName=request.getParameter("jobName");
		if (!StringUtils.isEmpty(jobName)) {
			jobName=URLDecoder.decode(jobName, "UTF-8");
			jobName=URLDecoder.decode(jobName, "UTF-8");
		}
		RecordResultBean resultBean = new RecordResultBean();
		try {
			
			Pager pager = new Pager(pageNum, pageSize);
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("jobName",jobName);
			pager.setKeys(map);
			pager = taskJobService.findPage(pager);
			if (pager == null || pager.getTotalCount() == 0) {
				resultBean.setResult(false);

			} else {
				resultBean.setResult(true);
				resultBean.setBean(pager);
			}
			
		}catch(Exception ex) {
			log.warn(JDKStackTrace.getJDKStrack(ex));
		}
		
		return resultBean;
	}

由于很久没来CSDN了,看到很多小伙伴在要程序源码,其实这篇文章也是我转的,原文也没有源码。不过根据原文和查看的一些资料做了一个定时发布天气微博的程序,SHH+easyui架构的,也实现了页面控制任务的功能,由于时间很长了,源码仅作参考,下载地址:

http://download.csdn.net/detail/a78460750/9865995

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

定时任务-quartz的使用,实现可页面化管理 的相关文章

  • leetcode----三数之和图解

    原题链接 https leetcode cn com problems 3sum 三数之和 给你一个包含 n 个整数的数组 nums 判断 nums 中是否存在三个元素 a b c 使得 a b c 0 请你找出所有满足条件且不重复的三元组

随机推荐

  • 微信小程序 getUserProfile直接进入fail函数,getUserProfile调用失败:fail can only be invoked by user TAP gesture.

    问题描述 小程序更改了调用用户信息的接口 详情 调用getUserProfile直接进入失败 返回的错误信息如下 getUserProfile fail can only be invoked by user TAP gesture 大概意
  • chubby——用于松耦合分布式系统的锁服务

    chubby 用于松耦合分布式系统的锁服务 首先 Chubby是什么 Chubby主要用于解决分布式一致性问题 在一个分布式系统中 有一组的Process 它们需要确定一个Value 于是每个Process都提出了一个Value 一致性就是
  • Spyder中全大写变量未显示

    比如这里的GT 之前怎么都不显示 参考 Spyder 变量无显示问题 将 Exclude all uppercase variables前面的对钩去掉即可 Exclude all uppercase variables 不显示全部大写变量去
  • linux下FTP服务启动与关闭命令

    查看FTP服务是否运行中 service vsftpd status 查看本地是否含有包含ftp的进程开启 ps ef grep ftp FTP设置开机自动运行 chkconfig vsftpd on 关闭FTP开机自动运行 chkconf
  • 游戏开发unity杂项知识系列:PC限制同个游戏程序只能运行一个

    unity出PC包很多时候要限制包的运行数量 实现一台电脑只能运行一个包只需要在出包的时候将Player Settings gt Resolution and Presentation 中的Force Single Instance 勾上就
  • 盘点:2012中国互联网大会十大亮点

    9月11日 14日 2012中国互联网大会在北京国际会议中心隆重举行 针对移动互联网 电子商务 云计算 物联网 网络视频 网络营销 网络宁静 垃圾信息治理 创业等领域 16场论坛先后上演 166位国内外嘉宾做精彩演讲 吸引265家媒体深度报
  • 【2022版】Java多线程与高并发面试题总结,108道题含答案解析。

    前言 最近面试的小伙伴很多 对此我整理了一份Java面试题手册 基础知识 JavaOOP Java集合 泛型面试题 Java异常面试题 Java中的IO与NIO面试题 Java反射 Java序列化 Java注解 多线程 并发 JVM Mys
  • set要点

    set分为set和multisets 前者元素不能重复 后者允许 set通常是以平衡二叉树完成的 由于set和map十分类似 所以本文篇幅较短 主要聚焦于一些set比较特殊的部分 set特点 由于二叉树搜索元素时的良好性能 其搜索函数算法具
  • esp32CAM环境安装教程---串口驱动安装

    前言 1 本人安装好arduino 的ESP32环境之后 发现一直下载不进去程序 一直说Cannot configure port something went wrong Original message PermissionError
  • pytorch实现style transfer

    说是实现 其实并不是我自己实现的 亮出代码 https github com yunjey pytorch tutorial tree master tutorials 03 advanced neural style transfer c
  • 【计算机网络】实验报告二:Wireshark实验

    Wireshark实验 实验准备 1 数据链路层 1 实作一 熟悉 Ethernet 帧结构 2 实作二 了解子网内 外通信时的 MAC 地址 3 实作三 掌握 ARP 解析过程 2 网络层 1 实作一 熟悉 IP 包结构 2 实作二 IP
  • 尚硅谷-宋红康-MySQL高级性能篇

    尚硅谷 宋红康 MySQL高级性能篇 第1章 Linux下MySQL的安装与使用 1 安装前说明 1 1 Linux系统及工具准备 二级目录 三级目录 第1章 Linux下MySQL的安装与使用 1 安装前说明 1 1 Linux系统及工具
  • 华为Atlas开发环境(ATC环境)搭建

    此博文主要用于指导在非昇腾AI设备上安装开发环境 用于代码开发及ATC模型转换等功能 以下所有操作建议在root用户下进行 可以省去很多麻烦 1 准备软件包 若开发环境为x86 64架构 而运行环境为aarch64架构 则开发环境上需要同时
  • cv2.error: Unknown C++ exception from OpenCV code

    超链接 深度学习工作常用方法汇总 矩阵维度变化 图片 视频等操作 包含 torch numpy opencv等 原因 ndarray经过切片后 会出现内存不连续的情况 当不连续时 保存就会报错 解决办法 frame np ascontigu
  • 在子工程中禁用的父工程的 maven 插件

    以 mybatis generator maven plugin 插件为例 在父工程中添加了 mybatis generator maven plugin 插件 想要在子工程禁用 则在对应子工程 pom 中添加 如下内容
  • App数据抓取(抓包工具使用)

    文章目录 fiddler使用 移动端 mitmproxy mitmdump 基础实战 使用Python抓取数据 小结 fiddler使用 基础篇介绍了如何设置fiddler做代理 这里继续介绍使用方法 在file中可以选择开始 停止抓包 可
  • 在安装project2010 64位时提示 “无法安装64位office,因为已有32位版本”解决方法...

    1 点击电脑左下角开始按钮 选择运行 或者window R快捷键 输入命名 regedit 2 弹出注册表编辑器窗口 选择HKEY CLASSES ROOT 打开子选项 3 然后找到Installer文件夹 展开文件列表 文件太大的话直接在
  • 87键键盘insert键使用方法

    87键党一枚 对于计算机工作者而言 104键键盘太鸡肋了 有很多键基本用不到 布局比较反人类 对于想要盲打全键的程序员 文字工作者而言 要按下控制键 得转动手腕甚至转动手肘 严重降低效率 87键实现了所有常用键的布局 可以盲打所有按键 对于
  • 马上看懂各种内聚类型(逻辑内聚、过程内聚、顺序内聚)

    各种内聚模式 内聚概念 内聚其实是一个模块内部各成分之间相关联程度的度量 用来表示说 你这个模块里面各个元素之间关系好不好 是不是每天勾肩搭背 还是冷眼相对或者是偶尔打个招呼 内聚类型 这里用 元素 来统一表达一个模块中各种操作 部分等说法
  • 定时任务-quartz的使用,实现可页面化管理

    定时任务 quartz的使用 实现可页面化管理 使用spring quartz实现定时任务的页面化管理 主要特点 1 时间表达式等信息配置在数据库中 从而实现页面化管理 2 可以手动执行或者停止单个任务 也可以使一个任务加入或者移出自动运行