`
liujiekasini0312
  • 浏览: 147659 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

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

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

说明:scheduler对象是spring管理定时任务的对象。
jobManager是我们自定义加载定时任务列表的对象,此对象加载所有任务列表后,将他们加入到自动运行列表。
二.jobManager代码:
  1. publicclassJobManagerimplementsInitializingBean{
  2. privatestaticfinalLoglog=LogFactory.getLog(JobManager.class);
  3. @Autowired
  4. TaskJobServicetaskJobService;
  5. @Autowired
  6. QuartzManagerquartzManager;
  7. @Override
  8. publicvoidafterPropertiesSet()throwsException{
  9. loadAllJob();
  10. }
  11. privatevoidloadAllJob(){
  12. List<TaskJob>list=taskJobService.getTaskList();
  13. quartzManager.enableCronSchedule(list);
  14. }
  15. }


说明:
1.实现spring中InitializingBean接口,并覆盖afterPropertiesSet方法,则该方法会在应用启动的时候而且其他servlet执行完成之后执行,此处用来加载所有定时任务,并加入定时任务自动运行列表。
2.quartzManager是我们自定义的定时任务管理类,用来实现我们文章开头说的功能。
三.QuartzManager代码
  1. @Controller
  2. publicclassQuartzManager{
  3. @Autowired
  4. Schedulerscheduler;
  5. privatestaticfinalLoglog=LogFactory.getLog(QuartzManager.class);
  6. publicvoidenableCronSchedule(List<TaskJob>list){
  7. for(TaskJobtask:list){
  8. SchedulingJobjob=newSchedulingJob();
  9. job.setJobId(task.getId());
  10. job.setJobName(task.getJobName());
  11. //job.setMemos(task.getNote());
  12. job.setCronExpression(task.getJobCronExpression());
  13. try{
  14. StringclassName=task.getJobClass().trim();
  15. Classclazz=Class.forName(className);
  16. job.setStateFulljobExecuteClass(clazz);
  17. }catch(Exceptione){
  18. e.printStackTrace();
  19. continue;
  20. }
  21. JobDataMapparamsMap=newJobDataMap();
  22. paramsMap.put("jobName",task.getJobName());
  23. if(task.getParamsKey1()!=null&&task.getParamsValue1()!=null){
  24. paramsMap.put(task.getParamsKey1(),task.getParamsValue1());
  25. }
  26. if(task.getParamsKey2()!=null&&task.getParamsValue2()!=null){
  27. paramsMap.put(task.getParamsKey2(),task.getParamsValue2());
  28. }
  29. if(task.getParamsKey3()!=null&&task.getParamsValue3()!=null){
  30. paramsMap.put(task.getParamsKey3(),task.getParamsValue3());
  31. }
  32. enableCronSchedule(job,paramsMap,true);
  33. log.info("系统结束初始化任务:"+task.getId()+":"+task.getJobName()+":"+task.getJobId());
  34. }
  35. }
  36. /**
  37. *启动一个自定义的job
  38. *
  39. *@paramschedulingJob
  40. *自定义的job
  41. *@paramparamsMap
  42. *传递给job执行的数据
  43. *@paramisStateFull
  44. *是否是一个同步定时任务,true:同步,false:异步
  45. *@return成功则返回true,否则返回false
  46. */
  47. publicbooleanenableCronSchedule(SchedulingJobschedulingJob,JobDataMapparamsMap,booleanisStateFull){
  48. if(schedulingJob==null){
  49. returnfalse;
  50. }
  51. try{
  52. //scheduler=(Scheduler)ApplicationHelper.getBean("scheduler");
  53. CronTriggertrigger=(CronTrigger)scheduler.getTrigger(schedulingJob.getTriggerName(),
  54. schedulingJob.getJobGroup());
  55. if(null==trigger){//如果不存在该trigger则创建一个
  56. JobDetailjobDetail=null;
  57. if(isStateFull){
  58. jobDetail=newJobDetail(schedulingJob.getJobId(),schedulingJob.getJobGroup(),
  59. schedulingJob.getStateFulljobExecuteClass());
  60. }else{
  61. jobDetail=newJobDetail(schedulingJob.getJobId(),schedulingJob.getJobGroup(),
  62. schedulingJob.getJobExecuteClass());
  63. }
  64. jobDetail.setJobDataMap(paramsMap);
  65. trigger=newCronTrigger(schedulingJob.getTriggerName(),schedulingJob.getJobGroup(),
  66. schedulingJob.getCronExpression());
  67. scheduler.scheduleJob(jobDetail,trigger);
  68. }else{
  69. //Trigger已存在,那么更新相应的定时设置
  70. trigger.setCronExpression(schedulingJob.getCronExpression());
  71. scheduler.rescheduleJob(trigger.getName(),trigger.getGroup(),trigger);
  72. }
  73. }catch(Exceptione){
  74. e.printStackTrace();
  75. returnfalse;
  76. }
  77. returntrue;
  78. }
  79. /**
  80. *禁用一个job
  81. *
  82. *@paramjobId
  83. *需要被禁用的job的ID
  84. *@paramjobGroupId
  85. *需要被警用的jobGroupId
  86. *@return成功则返回true,否则返回false
  87. */
  88. publicbooleandisableSchedule(StringjobId){
  89. if(jobId.equals("")){
  90. returnfalse;
  91. }
  92. try{
  93. StringjobGroupId="DEFAULT";
  94. Triggertrigger=getJobTrigger(jobId,jobGroupId);
  95. if(null!=trigger){
  96. scheduler.deleteJob(jobId,jobGroupId);
  97. }
  98. }catch(SchedulerExceptione){
  99. e.printStackTrace();
  100. returnfalse;
  101. }
  102. returntrue;
  103. }
  104. /**
  105. *得到job的详细信息
  106. *
  107. *@paramjobId
  108. *job的ID
  109. *@paramjobGroupId
  110. *job的组ID
  111. *@returnjob的详细信息,如果job不存在则返回null
  112. */
  113. publicJobDetailgetJobDetail(StringjobId,StringjobGroupId){
  114. if(jobId.equals("")||jobGroupId.equals("")||null==jobId||jobGroupId==null){
  115. returnnull;
  116. }
  117. try{
  118. returnscheduler.getJobDetail(jobId,jobGroupId);
  119. }catch(SchedulerExceptione){
  120. e.printStackTrace();
  121. returnnull;
  122. }
  123. }
  124. /**
  125. *得到job对应的Trigger
  126. *
  127. *@paramjobId
  128. *job的ID
  129. *@paramjobGroupId
  130. *job的组ID
  131. *@returnjob的Trigger,如果Trigger不存在则返回null
  132. */
  133. publicTriggergetJobTrigger(StringjobId,StringjobGroupId){
  134. if(jobId.equals("")||jobGroupId.equals("")||null==jobId||jobGroupId==null){
  135. returnnull;
  136. }
  137. try{
  138. returnscheduler.getTrigger(jobId+"Trigger",jobGroupId);
  139. }catch(SchedulerExceptione){
  140. e.printStackTrace();
  141. returnnull;
  142. }
  143. }
  144. }


说明:
1.主要方法有三个,启动一个任务,禁用一个任务,启动多个任务。启动即加入自动运行列表,禁用即移出自动运行列表。
2.TaskJob是一个任务对象,和数据库表结构相对应,后面给出数据库设计。
3.程序中有类似,
  1. 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代码:
  1. publicclassSchedulingJob{
  2. publicstaticfinalintJS_ENABLED=0;//任务启用状态
  3. publicstaticfinalintJS_DISABLED=1;//任务禁用状态
  4. publicstaticfinalintJS_DELETE=2;//任务已删除状态
  5. privateStringjobId;//任务的Id,一般为所定义Bean的ID
  6. privateStringjobName;//任务的描述
  7. privateStringjobGroup;//任务所属组的名称
  8. privateintjobStatus;//任务的状态,0:启用;1:禁用;2:已删除
  9. privateStringcronExpression;//定时任务运行时间表达式
  10. privateStringmemos;//任务描述
  11. privateClass<?>stateFulljobExecuteClass;//同步的执行类,需要从StatefulMethodInvokingJob继承
  12. privateClass<?>jobExecuteClass;//异步的执行类,需要从MethodInvokingJob继承
  13. /**
  14. *得到该job的Trigger名字
  15. *@return
  16. */
  17. publicStringgetTriggerName(){
  18. returnthis.getJobId()+"Trigger";
  19. }
  20. publicStringgetJobId(){
  21. returnjobId;
  22. }
  23. publicvoidsetJobId(StringjobId){
  24. this.jobId=jobId;
  25. }
  26. publicStringgetJobName(){
  27. returnjobName;
  28. }
  29. publicvoidsetJobName(StringjobName){
  30. this.jobName=jobName;
  31. }
  32. publicStringgetJobGroup(){
  33. if(jobGroup==null){
  34. jobGroup=Scheduler.DEFAULT_GROUP;
  35. }
  36. returnjobGroup;
  37. }
  38. publicvoidsetJobGroup(StringjobGroup){
  39. this.jobGroup=jobGroup;
  40. }
  41. publicintgetJobStatus(){
  42. returnjobStatus;
  43. }
  44. publicvoidsetJobStatus(intjobStatus){
  45. this.jobStatus=jobStatus;
  46. }
  47. publicStringgetCronExpression(){
  48. returncronExpression;
  49. }
  50. publicvoidsetCronExpression(StringcronExpression){
  51. this.cronExpression=cronExpression;
  52. }
  53. publicStringgetMemos(){
  54. returnmemos;
  55. }
  56. publicvoidsetMemos(Stringmemos){
  57. this.memos=memos;
  58. }
  59. publicClass<?>getStateFulljobExecuteClass(){
  60. returnstateFulljobExecuteClass;
  61. }
  62. publicvoidsetStateFulljobExecuteClass(Class<?>stateFulljobExecuteClass){
  63. this.stateFulljobExecuteClass=stateFulljobExecuteClass;
  64. }
  65. publicClass<?>getJobExecuteClass(){
  66. returnjobExecuteClass;
  67. }
  68. publicvoidsetJobExecuteClass(Class<?>jobExecuteClass){
  69. this.jobExecuteClass=jobExecuteClass;
  70. }
  71. publicstaticintgetJS_ENABLED(){
  72. returnJS_ENABLED;
  73. }
  74. publicstaticintgetJS_DISABLED(){
  75. returnJS_DISABLED;
  76. }
  77. publicstaticintgetJS_DELETE(){
  78. returnJS_DELETE;
  79. }
  80. }

五。具体JOB实现
只要继承QuartzJobBean类,覆盖executeInternal方法即可。在job中可能通过get方法的方式得到jobDetail对象中JobDataMap(详见QuartzManager类)中同名参数值。示例代码。
  1. @Controller
  2. publicclassContentJobextendsQuartzJobBean{
  3. @Autowired
  4. TaskJobServicetaskJobService;
  5. privateStringbeginDate;
  6. privateStringendDate;
  7. /**
  8. *手动执行任务
  9. *@paramrequest
  10. */
  11. @RequestMapping("/contentJobManual.do")
  12. publicvoidmanual(HttpServletRequestrequest){
  13. StringstartDate=request.getParameter("startDate");
  14. StringendDate=request.getParameter("endDate");
  15. TaskJobServicetaskJobService=(TaskJobService)ApplicationHelper.getBean("taskJobService");
  16. Map<String,String>param=newHashMap<String,String>();
  17. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  18. Stringtoday=sdf.format(newDate());
  19. if(StringUtils.isEmpty(startDate)){
  20. param.put("beginDate",today);
  21. }else{
  22. param.put("beginDate",startDate);
  23. }
  24. if(StringUtils.isEmpty(endDate)){
  25. param.put("endDate",today);
  26. }else{
  27. param.put("endDate",endDate);
  28. }
  29. taskJobService.callStatisticContent(param);
  30. }
  31. @Override
  32. publicvoidexecuteInternal(JobExecutionContextcontext){
  33. TaskJobServicetaskJobService=(TaskJobService)ApplicationHelper.getBean("taskJobService");
  34. Map<String,String>param=newHashMap<String,String>();
  35. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  36. Stringtoday=sdf.format(newDate());
  37. if(StringUtils.isEmpty(beginDate)){
  38. param.put("beginDate",today);
  39. }else{
  40. param.put("beginDate",beginDate);
  41. }
  42. if(StringUtils.isEmpty(endDate)){
  43. param.put("endDate",today);
  44. }else{
  45. param.put("endDate",endDate);
  46. }
  47. taskJobService.callStatisticContent(param);
  48. }
  49. publicStringgetBeginDate(){
  50. returnbeginDate;
  51. }
  52. publicvoidsetBeginDate(StringbeginDate){
  53. this.beginDate=beginDate;
  54. }
  55. publicStringgetEndDate(){
  56. returnendDate;
  57. }
  58. publicvoidsetEndDate(StringendDate){
  59. this.endDate=endDate;
  60. }

六。手动执行一个任务。可以将该job类声明成一个@Controller。另外写一个方法如上例中的manual方法。
扩展:目前还不能将自动运行的方法和手动执行的方法(即executeInternal方法和manual方法)写成一个。因为自动运行的方法不是一个action类,它不在web环境中,是通过反射实现的。如果把executeInternal这个方法强行配置成具有web功能的方法(即类上面加@Controller,方法上面加@RequestMapping("/contentJobManual.do"))也是不行的,因为该方法没有HttpServletRequest对象,获取不了参数。除非你的定时任务没有参数。当然你也不能修改该方法的参数类型,因为他是覆盖QuartzJobBean的方法。
七。数据库设计。
  1. IDVARCHAR2(60)N
  2. JOB_CLASSVARCHAR2(255)N
  3. JOB_NAMEVARCHAR2(60)N
  4. JOB_CRON_EXPRESSIONVARCHAR2(60)N
  5. JOB_SERVICE_BEANVARCHAR2(60)Y
  6. PARAMS_KEY1VARCHAR2(60)Y
  7. PARAMS_VALUE1VARCHAR2(60)Y
  8. PARAMS_KEY2VARCHAR2(60)Y
  9. PARAMS_VALUE2VARCHAR2(60)Y
  10. PARAMS_KEY3VARCHAR2(60)Y
  11. PARAMS_VALUE3VARCHAR2(60)Y
  12. NOTEVARCHAR2(255)Y
  13. JOB_STATUSVARCHAR2(1)Y
  14. UPDATETIMEDATEY
  15. JOB_AUTORUNVARCHAR2(1)Y
  16. JOB_GROUPVARCHAR2(60)Y

说明:JOB_STATUS表示是否有效任务,JOB_AUTORUN表示是否自动运行,JOB_SERVICE_BEAN表示手动执行的请求URL,JOB_CLASS表示JOB类的全路径,JOB_GROUP表示任务属于哪个组,方便对任务的分组管理(批量启动,禁止等),区别于quartz的API所要求的同名参数,其实也可以把这个值传给API。其它字段比较好理解。该表对应的bean是taskjob。
八。页面管理。
主要功能是将一个任务加入或者移出自动运行队列(通过quartzManager对象)。和任务的增删查改。示例代码如下:
  1. @Controller
  2. publicclassTaskJobAction{
  3. privatestaticfinalLoglog=LogFactory.getLog(TaskJobAction.class);
  4. @Autowired
  5. TaskJobServicetaskJobService;
  6. @Autowired
  7. QuartzManagerquartzManager;
  8. @RequestMapping("/enableTask.do")
  9. publicvoidenableTask(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  10. StringparameterStr="";
  11. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  12. parameterStr=StringUtils.trim(parameterStr);
  13. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  14. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  15. Stringid=p.get("id");
  16. if(!StringUtils.isEmpty(id)){
  17. TaskJobtask=taskJobService.getTaskById(id);
  18. List<TaskJob>list=newArrayList<TaskJob>();
  19. list.add(task);
  20. quartzManager.enableCronSchedule(list);
  21. task.setJobEnabled("Y");
  22. taskJobService.update(task);//将任务设置成自动运行状态
  23. }
  24. }
  25. @RequestMapping("/disableTask.do")
  26. publicvoiddisableTask(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  27. StringparameterStr="";
  28. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  29. parameterStr=StringUtils.trim(parameterStr);
  30. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  31. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  32. Stringid=p.get("id");
  33. if(!StringUtils.isEmpty(id)){
  34. TaskJobtask=taskJobService.getTaskById(id);
  35. quartzManager.disableSchedule(task.getJobId());
  36. task.setJobEnabled("N");
  37. taskJobService.update(task);//将任务设置成非运行状态
  38. }
  39. }
  40. @RequestMapping("/add.do")
  41. publicvoidadd(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  42. StringparameterStr="";
  43. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  44. parameterStr=StringUtils.trim(parameterStr);
  45. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  46. Stringjobjson=p.get("jobjson");
  47. jobjson=URLDecoder.decode(jobjson,"utf-8");
  48. TaskJobtask=JsonUtil.toObject(jobjson,TaskJob.class);
  49. StringjobName=URLDecoder.decode(task.getJobName(),"utf-8");
  50. task.setJobName(jobName);
  51. if(!StringUtils.isEmpty(jobjson)){
  52. taskJobService.insert(task);
  53. }
  54. }
  55. @RequestMapping("/update.do")
  56. publicvoidupdate(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  57. StringparameterStr="";
  58. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  59. parameterStr=StringUtils.trim(parameterStr);
  60. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  61. Stringjobjson=p.get("jobjson");
  62. jobjson=URLDecoder.decode(jobjson,"utf-8");
  63. TaskJobtask=JsonUtil.toObject(jobjson,TaskJob.class);
  64. StringjobName=URLDecoder.decode(task.getJobName(),"utf-8");
  65. task.setJobName(jobName);
  66. if(!StringUtils.isEmpty(jobjson)){
  67. taskJobService.update(task);
  68. }
  69. }
  70. @RequestMapping("/delete.do")
  71. publicvoiddelete(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  72. StringparameterStr="";
  73. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  74. parameterStr=StringUtils.trim(parameterStr);
  75. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  76. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  77. StringidStr=p.get("idStr");
  78. if(!StringUtils.isEmpty(idStr)){
  79. taskJobService.delete(idStr);
  80. }
  81. }
  82. @ResponseBody
  83. @RequestMapping("/taskList.do")
  84. publicRecordResultBeanlist(HttpServletRequestrequest,HttpServletResponseresponse,@RequestParam("pageSize")intpageSize,
  85. @RequestParam("startIndex")intstartIndex)throwsIOException{
  86. intpageNum=startIndex/pageSize+1;
  87. StringstartDate=request.getParameter("startDate");
  88. StringendDate=request.getParameter("endDate");
  89. StringjobName=request.getParameter("jobName");
  90. if(!StringUtils.isEmpty(jobName)){
  91. jobName=URLDecoder.decode(jobName,"UTF-8");
  92. jobName=URLDecoder.decode(jobName,"UTF-8");
  93. }
  94. RecordResultBeanresultBean=newRecordResultBean();
  95. try{
  96. Pagerpager=newPager(pageNum,pageSize);
  97. Map<String,Object>map=newHashMap<String,Object>();
  98. map.put("jobName",jobName);
  99. pager.setKeys(map);
  100. pager=taskJobService.findPage(pager);
  101. if(pager==null||pager.getTotalCount()==0){
  102. resultBean.setResult(false);
  103. }else{
  104. resultBean.setResult(true);
  105. resultBean.setBean(pager);
  106. }
  107. }catch(Exceptionex){
  108. log.warn(JDKStackTrace.getJDKStrack(ex));
  109. }
  110. returnresultBean;
  111. }
定时任务-quartz的使用,实现可页面化管理
使用spring+quartz实现定时任务的页面化管理。主要特点:
1.时间表达式等信息配置在数据库中,从而实现页面化管理。
2.可以手动执行或者停止单个任务,也可以使一个任务加入或者移出自动运行列表。

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

说明:scheduler对象是spring管理定时任务的对象。
jobManager是我们自定义加载定时任务列表的对象,此对象加载所有任务列表后,将他们加入到自动运行列表。
二.jobManager代码:
  1. publicclassJobManagerimplementsInitializingBean{
  2. privatestaticfinalLoglog=LogFactory.getLog(JobManager.class);
  3. @Autowired
  4. TaskJobServicetaskJobService;
  5. @Autowired
  6. QuartzManagerquartzManager;
  7. @Override
  8. publicvoidafterPropertiesSet()throwsException{
  9. loadAllJob();
  10. }
  11. privatevoidloadAllJob(){
  12. List<TaskJob>list=taskJobService.getTaskList();
  13. quartzManager.enableCronSchedule(list);
  14. }
  15. }


说明:
1.实现spring中InitializingBean接口,并覆盖afterPropertiesSet方法,则该方法会在应用启动的时候而且其他servlet执行完成之后执行,此处用来加载所有定时任务,并加入定时任务自动运行列表。
2.quartzManager是我们自定义的定时任务管理类,用来实现我们文章开头说的功能。
三.QuartzManager代码
  1. @Controller
  2. publicclassQuartzManager{
  3. @Autowired
  4. Schedulerscheduler;
  5. privatestaticfinalLoglog=LogFactory.getLog(QuartzManager.class);
  6. publicvoidenableCronSchedule(List<TaskJob>list){
  7. for(TaskJobtask:list){
  8. SchedulingJobjob=newSchedulingJob();
  9. job.setJobId(task.getId());
  10. job.setJobName(task.getJobName());
  11. //job.setMemos(task.getNote());
  12. job.setCronExpression(task.getJobCronExpression());
  13. try{
  14. StringclassName=task.getJobClass().trim();
  15. Classclazz=Class.forName(className);
  16. job.setStateFulljobExecuteClass(clazz);
  17. }catch(Exceptione){
  18. e.printStackTrace();
  19. continue;
  20. }
  21. JobDataMapparamsMap=newJobDataMap();
  22. paramsMap.put("jobName",task.getJobName());
  23. if(task.getParamsKey1()!=null&&task.getParamsValue1()!=null){
  24. paramsMap.put(task.getParamsKey1(),task.getParamsValue1());
  25. }
  26. if(task.getParamsKey2()!=null&&task.getParamsValue2()!=null){
  27. paramsMap.put(task.getParamsKey2(),task.getParamsValue2());
  28. }
  29. if(task.getParamsKey3()!=null&&task.getParamsValue3()!=null){
  30. paramsMap.put(task.getParamsKey3(),task.getParamsValue3());
  31. }
  32. enableCronSchedule(job,paramsMap,true);
  33. log.info("系统结束初始化任务:"+task.getId()+":"+task.getJobName()+":"+task.getJobId());
  34. }
  35. }
  36. /**
  37. *启动一个自定义的job
  38. *
  39. *@paramschedulingJob
  40. *自定义的job
  41. *@paramparamsMap
  42. *传递给job执行的数据
  43. *@paramisStateFull
  44. *是否是一个同步定时任务,true:同步,false:异步
  45. *@return成功则返回true,否则返回false
  46. */
  47. publicbooleanenableCronSchedule(SchedulingJobschedulingJob,JobDataMapparamsMap,booleanisStateFull){
  48. if(schedulingJob==null){
  49. returnfalse;
  50. }
  51. try{
  52. //scheduler=(Scheduler)ApplicationHelper.getBean("scheduler");
  53. CronTriggertrigger=(CronTrigger)scheduler.getTrigger(schedulingJob.getTriggerName(),
  54. schedulingJob.getJobGroup());
  55. if(null==trigger){//如果不存在该trigger则创建一个
  56. JobDetailjobDetail=null;
  57. if(isStateFull){
  58. jobDetail=newJobDetail(schedulingJob.getJobId(),schedulingJob.getJobGroup(),
  59. schedulingJob.getStateFulljobExecuteClass());
  60. }else{
  61. jobDetail=newJobDetail(schedulingJob.getJobId(),schedulingJob.getJobGroup(),
  62. schedulingJob.getJobExecuteClass());
  63. }
  64. jobDetail.setJobDataMap(paramsMap);
  65. trigger=newCronTrigger(schedulingJob.getTriggerName(),schedulingJob.getJobGroup(),
  66. schedulingJob.getCronExpression());
  67. scheduler.scheduleJob(jobDetail,trigger);
  68. }else{
  69. //Trigger已存在,那么更新相应的定时设置
  70. trigger.setCronExpression(schedulingJob.getCronExpression());
  71. scheduler.rescheduleJob(trigger.getName(),trigger.getGroup(),trigger);
  72. }
  73. }catch(Exceptione){
  74. e.printStackTrace();
  75. returnfalse;
  76. }
  77. returntrue;
  78. }
  79. /**
  80. *禁用一个job
  81. *
  82. *@paramjobId
  83. *需要被禁用的job的ID
  84. *@paramjobGroupId
  85. *需要被警用的jobGroupId
  86. *@return成功则返回true,否则返回false
  87. */
  88. publicbooleandisableSchedule(StringjobId){
  89. if(jobId.equals("")){
  90. returnfalse;
  91. }
  92. try{
  93. StringjobGroupId="DEFAULT";
  94. Triggertrigger=getJobTrigger(jobId,jobGroupId);
  95. if(null!=trigger){
  96. scheduler.deleteJob(jobId,jobGroupId);
  97. }
  98. }catch(SchedulerExceptione){
  99. e.printStackTrace();
  100. returnfalse;
  101. }
  102. returntrue;
  103. }
  104. /**
  105. *得到job的详细信息
  106. *
  107. *@paramjobId
  108. *job的ID
  109. *@paramjobGroupId
  110. *job的组ID
  111. *@returnjob的详细信息,如果job不存在则返回null
  112. */
  113. publicJobDetailgetJobDetail(StringjobId,StringjobGroupId){
  114. if(jobId.equals("")||jobGroupId.equals("")||null==jobId||jobGroupId==null){
  115. returnnull;
  116. }
  117. try{
  118. returnscheduler.getJobDetail(jobId,jobGroupId);
  119. }catch(SchedulerExceptione){
  120. e.printStackTrace();
  121. returnnull;
  122. }
  123. }
  124. /**
  125. *得到job对应的Trigger
  126. *
  127. *@paramjobId
  128. *job的ID
  129. *@paramjobGroupId
  130. *job的组ID
  131. *@returnjob的Trigger,如果Trigger不存在则返回null
  132. */
  133. publicTriggergetJobTrigger(StringjobId,StringjobGroupId){
  134. if(jobId.equals("")||jobGroupId.equals("")||null==jobId||jobGroupId==null){
  135. returnnull;
  136. }
  137. try{
  138. returnscheduler.getTrigger(jobId+"Trigger",jobGroupId);
  139. }catch(SchedulerExceptione){
  140. e.printStackTrace();
  141. returnnull;
  142. }
  143. }
  144. }


说明:
1.主要方法有三个,启动一个任务,禁用一个任务,启动多个任务。启动即加入自动运行列表,禁用即移出自动运行列表。
2.TaskJob是一个任务对象,和数据库表结构相对应,后面给出数据库设计。
3.程序中有类似,
  1. 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代码:
  1. publicclassSchedulingJob{
  2. publicstaticfinalintJS_ENABLED=0;//任务启用状态
  3. publicstaticfinalintJS_DISABLED=1;//任务禁用状态
  4. publicstaticfinalintJS_DELETE=2;//任务已删除状态
  5. privateStringjobId;//任务的Id,一般为所定义Bean的ID
  6. privateStringjobName;//任务的描述
  7. privateStringjobGroup;//任务所属组的名称
  8. privateintjobStatus;//任务的状态,0:启用;1:禁用;2:已删除
  9. privateStringcronExpression;//定时任务运行时间表达式
  10. privateStringmemos;//任务描述
  11. privateClass<?>stateFulljobExecuteClass;//同步的执行类,需要从StatefulMethodInvokingJob继承
  12. privateClass<?>jobExecuteClass;//异步的执行类,需要从MethodInvokingJob继承
  13. /**
  14. *得到该job的Trigger名字
  15. *@return
  16. */
  17. publicStringgetTriggerName(){
  18. returnthis.getJobId()+"Trigger";
  19. }
  20. publicStringgetJobId(){
  21. returnjobId;
  22. }
  23. publicvoidsetJobId(StringjobId){
  24. this.jobId=jobId;
  25. }
  26. publicStringgetJobName(){
  27. returnjobName;
  28. }
  29. publicvoidsetJobName(StringjobName){
  30. this.jobName=jobName;
  31. }
  32. publicStringgetJobGroup(){
  33. if(jobGroup==null){
  34. jobGroup=Scheduler.DEFAULT_GROUP;
  35. }
  36. returnjobGroup;
  37. }
  38. publicvoidsetJobGroup(StringjobGroup){
  39. this.jobGroup=jobGroup;
  40. }
  41. publicintgetJobStatus(){
  42. returnjobStatus;
  43. }
  44. publicvoidsetJobStatus(intjobStatus){
  45. this.jobStatus=jobStatus;
  46. }
  47. publicStringgetCronExpression(){
  48. returncronExpression;
  49. }
  50. publicvoidsetCronExpression(StringcronExpression){
  51. this.cronExpression=cronExpression;
  52. }
  53. publicStringgetMemos(){
  54. returnmemos;
  55. }
  56. publicvoidsetMemos(Stringmemos){
  57. this.memos=memos;
  58. }
  59. publicClass<?>getStateFulljobExecuteClass(){
  60. returnstateFulljobExecuteClass;
  61. }
  62. publicvoidsetStateFulljobExecuteClass(Class<?>stateFulljobExecuteClass){
  63. this.stateFulljobExecuteClass=stateFulljobExecuteClass;
  64. }
  65. publicClass<?>getJobExecuteClass(){
  66. returnjobExecuteClass;
  67. }
  68. publicvoidsetJobExecuteClass(Class<?>jobExecuteClass){
  69. this.jobExecuteClass=jobExecuteClass;
  70. }
  71. publicstaticintgetJS_ENABLED(){
  72. returnJS_ENABLED;
  73. }
  74. publicstaticintgetJS_DISABLED(){
  75. returnJS_DISABLED;
  76. }
  77. publicstaticintgetJS_DELETE(){
  78. returnJS_DELETE;
  79. }
  80. }

五。具体JOB实现
只要继承QuartzJobBean类,覆盖executeInternal方法即可。在job中可能通过get方法的方式得到jobDetail对象中JobDataMap(详见QuartzManager类)中同名参数值。示例代码。
  1. @Controller
  2. publicclassContentJobextendsQuartzJobBean{
  3. @Autowired
  4. TaskJobServicetaskJobService;
  5. privateStringbeginDate;
  6. privateStringendDate;
  7. /**
  8. *手动执行任务
  9. *@paramrequest
  10. */
  11. @RequestMapping("/contentJobManual.do")
  12. publicvoidmanual(HttpServletRequestrequest){
  13. StringstartDate=request.getParameter("startDate");
  14. StringendDate=request.getParameter("endDate");
  15. TaskJobServicetaskJobService=(TaskJobService)ApplicationHelper.getBean("taskJobService");
  16. Map<String,String>param=newHashMap<String,String>();
  17. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  18. Stringtoday=sdf.format(newDate());
  19. if(StringUtils.isEmpty(startDate)){
  20. param.put("beginDate",today);
  21. }else{
  22. param.put("beginDate",startDate);
  23. }
  24. if(StringUtils.isEmpty(endDate)){
  25. param.put("endDate",today);
  26. }else{
  27. param.put("endDate",endDate);
  28. }
  29. taskJobService.callStatisticContent(param);
  30. }
  31. @Override
  32. publicvoidexecuteInternal(JobExecutionContextcontext){
  33. TaskJobServicetaskJobService=(TaskJobService)ApplicationHelper.getBean("taskJobService");
  34. Map<String,String>param=newHashMap<String,String>();
  35. SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd");
  36. Stringtoday=sdf.format(newDate());
  37. if(StringUtils.isEmpty(beginDate)){
  38. param.put("beginDate",today);
  39. }else{
  40. param.put("beginDate",beginDate);
  41. }
  42. if(StringUtils.isEmpty(endDate)){
  43. param.put("endDate",today);
  44. }else{
  45. param.put("endDate",endDate);
  46. }
  47. taskJobService.callStatisticContent(param);
  48. }
  49. publicStringgetBeginDate(){
  50. returnbeginDate;
  51. }
  52. publicvoidsetBeginDate(StringbeginDate){
  53. this.beginDate=beginDate;
  54. }
  55. publicStringgetEndDate(){
  56. returnendDate;
  57. }
  58. publicvoidsetEndDate(StringendDate){
  59. this.endDate=endDate;
  60. }

六。手动执行一个任务。可以将该job类声明成一个@Controller。另外写一个方法如上例中的manual方法。
扩展:目前还不能将自动运行的方法和手动执行的方法(即executeInternal方法和manual方法)写成一个。因为自动运行的方法不是一个action类,它不在web环境中,是通过反射实现的。如果把executeInternal这个方法强行配置成具有web功能的方法(即类上面加@Controller,方法上面加@RequestMapping("/contentJobManual.do"))也是不行的,因为该方法没有HttpServletRequest对象,获取不了参数。除非你的定时任务没有参数。当然你也不能修改该方法的参数类型,因为他是覆盖QuartzJobBean的方法。
七。数据库设计。
  1. IDVARCHAR2(60)N
  2. JOB_CLASSVARCHAR2(255)N
  3. JOB_NAMEVARCHAR2(60)N
  4. JOB_CRON_EXPRESSIONVARCHAR2(60)N
  5. JOB_SERVICE_BEANVARCHAR2(60)Y
  6. PARAMS_KEY1VARCHAR2(60)Y
  7. PARAMS_VALUE1VARCHAR2(60)Y
  8. PARAMS_KEY2VARCHAR2(60)Y
  9. PARAMS_VALUE2VARCHAR2(60)Y
  10. PARAMS_KEY3VARCHAR2(60)Y
  11. PARAMS_VALUE3VARCHAR2(60)Y
  12. NOTEVARCHAR2(255)Y
  13. JOB_STATUSVARCHAR2(1)Y
  14. UPDATETIMEDATEY
  15. JOB_AUTORUNVARCHAR2(1)Y
  16. JOB_GROUPVARCHAR2(60)Y

说明:JOB_STATUS表示是否有效任务,JOB_AUTORUN表示是否自动运行,JOB_SERVICE_BEAN表示手动执行的请求URL,JOB_CLASS表示JOB类的全路径,JOB_GROUP表示任务属于哪个组,方便对任务的分组管理(批量启动,禁止等),区别于quartz的API所要求的同名参数,其实也可以把这个值传给API。其它字段比较好理解。该表对应的bean是taskjob。
八。页面管理。
主要功能是将一个任务加入或者移出自动运行队列(通过quartzManager对象)。和任务的增删查改。示例代码如下:
  1. @Controller
  2. publicclassTaskJobAction{
  3. privatestaticfinalLoglog=LogFactory.getLog(TaskJobAction.class);
  4. @Autowired
  5. TaskJobServicetaskJobService;
  6. @Autowired
  7. QuartzManagerquartzManager;
  8. @RequestMapping("/enableTask.do")
  9. publicvoidenableTask(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  10. StringparameterStr="";
  11. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  12. parameterStr=StringUtils.trim(parameterStr);
  13. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  14. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  15. Stringid=p.get("id");
  16. if(!StringUtils.isEmpty(id)){
  17. TaskJobtask=taskJobService.getTaskById(id);
  18. List<TaskJob>list=newArrayList<TaskJob>();
  19. list.add(task);
  20. quartzManager.enableCronSchedule(list);
  21. task.setJobEnabled("Y");
  22. taskJobService.update(task);//将任务设置成自动运行状态
  23. }
  24. }
  25. @RequestMapping("/disableTask.do")
  26. publicvoiddisableTask(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  27. StringparameterStr="";
  28. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  29. parameterStr=StringUtils.trim(parameterStr);
  30. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  31. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  32. Stringid=p.get("id");
  33. if(!StringUtils.isEmpty(id)){
  34. TaskJobtask=taskJobService.getTaskById(id);
  35. quartzManager.disableSchedule(task.getJobId());
  36. task.setJobEnabled("N");
  37. taskJobService.update(task);//将任务设置成非运行状态
  38. }
  39. }
  40. @RequestMapping("/add.do")
  41. publicvoidadd(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  42. StringparameterStr="";
  43. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  44. parameterStr=StringUtils.trim(parameterStr);
  45. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  46. Stringjobjson=p.get("jobjson");
  47. jobjson=URLDecoder.decode(jobjson,"utf-8");
  48. TaskJobtask=JsonUtil.toObject(jobjson,TaskJob.class);
  49. StringjobName=URLDecoder.decode(task.getJobName(),"utf-8");
  50. task.setJobName(jobName);
  51. if(!StringUtils.isEmpty(jobjson)){
  52. taskJobService.insert(task);
  53. }
  54. }
  55. @RequestMapping("/update.do")
  56. publicvoidupdate(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  57. StringparameterStr="";
  58. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  59. parameterStr=StringUtils.trim(parameterStr);
  60. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  61. Stringjobjson=p.get("jobjson");
  62. jobjson=URLDecoder.decode(jobjson,"utf-8");
  63. TaskJobtask=JsonUtil.toObject(jobjson,TaskJob.class);
  64. StringjobName=URLDecoder.decode(task.getJobName(),"utf-8");
  65. task.setJobName(jobName);
  66. if(!StringUtils.isEmpty(jobjson)){
  67. taskJobService.update(task);
  68. }
  69. }
  70. @RequestMapping("/delete.do")
  71. publicvoiddelete(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOException{
  72. StringparameterStr="";
  73. parameterStr=IOUtils.toString(request.getInputStream(),InputConstant.CHAR_SET);
  74. parameterStr=StringUtils.trim(parameterStr);
  75. parameterStr=URLDecoder.decode(parameterStr,"utf-8");
  76. Map<String,String>p=JsonUtil.getParameterMap(parameterStr);
  77. StringidStr=p.get("idStr");
  78. if(!StringUtils.isEmpty(idStr)){
  79. taskJobService.delete(idStr);
  80. }
  81. }
  82. @ResponseBody
  83. @RequestMapping("/taskList.do")
  84. publicRecordResultBeanlist(HttpServletRequestrequest,HttpServletResponseresponse,@RequestParam("pageSize")intpageSize,
  85. @RequestParam("startIndex")intstartIndex)throwsIOException{
  86. intpageNum=startIndex/pageSize+1;
  87. StringstartDate=request.getParameter("startDate");
  88. StringendDate=request.getParameter("endDate");
  89. StringjobName=request.getParameter("jobName");
  90. if(!StringUtils.isEmpty(jobName)){
  91. jobName=URLDecoder.decode(jobName,"UTF-8");
  92. jobName=URLDecoder.decode(jobName,"UTF-8");
  93. }
  94. RecordResultBeanresultBean=newRecordResultBean();
  95. try{
  96. Pagerpager=newPager(pageNum,pageSize);
  97. Map<String,Object>map=newHashMap<String,Object>();
  98. map.put("jobName",jobName);
  99. pager.setKeys(map);
  100. pager=taskJobService.findPage(pager);
  101. if(pager==null||pager.getTotalCount()==0){
  102. resultBean.setResult(false);
  103. }else{
  104. resultBean.setResult(true);
  105. resultBean.setBean(pager);
  106. }
  107. }catch(Exceptionex){
  108. log.warn(JDKStackTrace.getJDKStrack(ex));
  109. }
  110. returnresultBean;
  111. }
分享到:
评论

相关推荐

    quartz demo

    Quartz 是一个开源的工作调度框架,常用于Java应用程序中实现定时任务的管理。Spring框架与Quartz的整合,使得在Spring应用中配置和管理定时任务变得更加便捷。在"quartz demo"这个项目中,我们将探讨如何在Spring...

    定时任务,JSP

    在实际项目中,通常会结合使用这些工具和方法,以实现灵活、可扩展的定时任务系统。例如,创建一个简单的JSP页面用于展示定时任务的状态,或者提供一个表单供用户添加新的定时任务。这需要对JSP语法、Servlet以及...

    quartz1.86+spring3.2测试实例

    这两个框架的结合使得开发者能够方便地在Spring管理的上下文中配置和控制Quartz定时任务,提高了应用程序的灵活性和可维护性。 Quartz 1.86是Quartz的一个较早版本,它支持创建、调度和执行任务。通过定义Job类来...

    页面管理.zip

    总的来说,"页面管理.zip"可能是一个集成了定时任务管理的Web工具,可以帮助开发者和运维人员更有效地管理和优化网站的各个页面,同时利用定时任务实现后台的自动化操作。通过这样的工具,可以提高工作效率,降低...

    企业后台管理基础框架 hsweb.zip

    定时调度支持,可在页面配置定时任务,编写任务脚本执行。演示示例:demo.hsweb.me测试用户:test (test2,test3,test4....) 密码:123456演示项目源码:hsweb-demo技术选型第三方:MVC:spring-boot. 开箱即用,学习成本低,...

    Maven+SpringMVC+SpringTask定时任务

    【标签】"定时任务"表明这个项目的核心功能之一是实现定期执行的自动化任务。在Java Web开发中,定时任务常常用于处理那些不需要立即响应但需要按计划进行的工作,例如清理过期数据、发送邮件通知、统计分析等。 ...

    quartz-golang-with-react-ui:演示版

    React UI则为用户提供了一个图形化界面,可以方便地查看、创建、编辑和删除定时任务。 【标签】"HTML"表明项目涉及到网页开发,HTML(超文本标记语言)是构建网页的基本元素,通常与CSS和JavaScript一起使用来构建...

    若依博客(ruoyi-blog-master.zip)

    定时任务:Quartz。 数据库连接池:Druid。 工具类:Fastjson。 除若依原有的功能外添加博客功能 导航管理 :对博客前台显示配置,可以设置页面,也可设置分类 分类管理:对博客进行分类 标签管理:略 博客管理:对...

    java springboot 前后台博客系统,毕业设计,设计报告

    前后台博客系统 功能:用户角色菜单管理等。 导航管理 :对博客前台显示配置,可以...5. 定时任务:Quartz。 6. 数据库连接池:Druid。 7. 工具类:Fastjson。 环境:java1.8 ,mysql5.7以上,idea。 源码+数据库文件。

    java学习文档

    - **实现方法**:利用注解方式配置Quartz定时任务。 - **日志改进** - **改进目的**:优化日志记录方式,提高日志的可读性和可维护性。 - **配置增量覆盖** - **改进目的**:允许增量覆盖配置文件,便于灵活...

    springboot完整架构,带后台管理

    - Quartz/Spring Scheduler:任务调度,实现定时任务。 综上所述,这个项目是一个全面的SpringBoot应用,具备后台管理功能,并与MySQL数据库集成。开发者可以在此基础上进行业务逻辑开发,实现高效且稳定的系统...

    黑马面试宝典知识点复习

    - **使用场景**:定时任务、计划任务等。 - **监控**:可以使用Quartz提供的API来监控任务执行状态。 #### MQ(消息队列) - **RabbitMQ**: - **定义**:一种消息中间件。 - **优点**:高可用性、支持多种语言、...

    基于JavaWeb的推荐数据后台管理系统的设计与实现 (2).docx

    - **定时任务**:使用Quartz实现定时任务调度,定期执行数据同步和备份操作。 - **数据迁移工具**:利用Flyway进行数据库版本控制和迁移,确保数据一致性。 #### 五、测试与部署 ##### 1. 单元测试 - 使用JUnit...

    基于springboot OA自动化办公系统源码.zip

    - **任务管理**:实现任务的创建、分配、跟踪和完成,可能涉及到Quartz或Spring Task进行定时任务的调度。 - **审批流程**:可能使用工作流引擎如Activiti或Flowable,实现流程定义和执行。 - **文档管理**:存储...

    学习java的30个目标.txt

    - **应用场景**:日志管理、定时任务调度等。 #### 目标21:掌握网络通信与缓存技术 - **技术框架**:JGroups、JCache等。 - **应用场景**:分布式系统的通信与数据缓存。 #### 目标22:学习全文搜索技术 - **...

    Beginning iOS 5 Development: Exploring the iOS SDK [Paperback]

    - **定时任务**:设定任务在特定时间自动执行。 #### 14. 图形绘制技术 - **Quartz 2D**:用于绘制简单的图形和文字。 - **OpenGL ES**:用于实现高质量的三维图形渲染。 #### 15. 触摸与手势识别 - **触摸事件*...

    J_HI 平台 及 开发文档

    4. **其他技术**:平台还集成了C3P0连接池、Quartz定时任务等技术。 #### 四、平台组成部分详解 1. **生成器** - **环境目录**:生成器需要特定的目录结构来进行配置和生成。 - **生成原理**:基于模板和配置...

    Spring Task.docx

    【Spring Task】定时任务在IT行业中扮演着至关重要的角色,特别是在大数据处理、系统维护和自动化流程中。本文将深入探讨Spring框架内置的定时任务模块,Spring Task,以及如何在实际业务场景中应用它。 首先,让...

Global site tag (gtag.js) - Google Analytics