java定时框架Quartz的简单应用(附:读取properties文件参数代码)
2017-01-11 18:19
821 查看
1. 实现一个简单的定时任务
1.1 步骤如下:
(1)下载Quartz的压缩包,并解压,其中lib文件夹下的jar包为Quartz需要用到的包,如图1(2)简单的定时任务,在每分钟输出一次hellojob
//测试版本为quartz1.80,在quartz2.23下会报错 public class QuartzTest1 { public static void main(String[] args) { JobDetail jobDetail = new JobDetail("Hello_Job","Hello_Job_Group",HelloJob.class); JobDataMap dataMap = new JobDataMap(); jobDetail.setJobDataMap(dataMap); CronTrigger trigger = new CronTrigger("TriggerName","TriggerGroupName" ); try { SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory(); Scheduler scheduler = schedFact.getScheduler(); //时间格式:秒 分 时 日 月 年,*为任意 trigger.setCronExpression("0 * * * * ?"); scheduler.scheduleJob(jobDetail, trigger); if (!scheduler.isShutdown()) { scheduler.start(); //为定时作业调度预留时间 Thread.sleep(600000); scheduler.shutdown(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //分割线-------------------------------------------- //在quartz2.23的示例 public class QuartzTest1 { public static void main(String[] args) { SchedulerFactory sf = new StdSchedulerFactory(); try { Scheduler sched = sf.getScheduler(); Date nowTime = new Date(); System.out.println(nowTime); //将分秒数进位取整nowTime=15:40:28 runTime=15:41:00 Date runTime = DateBuilder.evenMinuteDate(nowTime); System.out.println(runTime); JobDetail job = JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build(); //单次定时任务 //Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build(); //多次循环定时任务"0/20 * * * * ?"从*年*月*日 *:*:00秒开始每20秒执行一次 CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(CronScheduleBuilder.cronSchedule("0/20 * * * * ?")) .build(); Date ft = sched.scheduleJob(job, trigger); System.out.println(job.getKey() + " has been scheduled to run at: " + ft + " and repeat based on expression: " + trigger.getCronExpression()); sched.start(); Thread.sleep(60000*5); sched.shutdown(true); } catch (Exception e) { // } } } //继承Job类的具体定时任务 public class HelloJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("hello job......start:"+new Date()); } }
2. Quartz中一些常用的方法(quartz2.23)
2.1 Scheduler类的一些方法
2.11 获取Scheduler对象
SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler();
2.12 将JobDetail对象与Trigger对象绑定到Scheduler对象上
Date ft = sched.scheduleJob(JobDetail job,Trigger trigger); //可绑定多个job及trigger返回的Date为第一次定时任务的开始执行时间
2.13 Scheduler对象的开始与结束
sched.start(); sched.shutdown(true);
2.14 重新执行绑定执行定时任务
sched.rescheduleJob(trigger.getKey(), trigger);
2.15 获取一些统计信息
SchedulerMetaData metaData = sched.getMetaData(); //获得绑定执行的job执行的次数 metaData.getNumberOfJobsExecuted();
2.2 JobDetail类的一些方法
2.21 创建JobDetail对象及设置基本属性
JobDetail job = org.quartz.JobBuilder.newJob(HelloJob.class).withIdentity("job1", "group1").build();
2.22 获取JobDetail对象job的的Identity信息
job.getKey();//打印结果为group1.job1(该job对象创建于2.21)
2.23 手动执行JobDetail(不创建Trigger)
JobDetail job = org.quartz.JobBuilder.newJob(SimpleJob.class).withIdentity("job8", "group1").storeDurably().build(); sched.addJob(job, true); sched.triggerJob(org.quartz.JobKey.jobKey("job8", "group1"));
2.24 通过JobDataMap和实现Job接口的execute()方法传参
JobDetail job1 = newJob(ColorJob.class).withIdentity("job1", "group1").build(); job1.getJobDataMap().put(ColorJob.FAVORITE_COLOR, "Green"); job1.getJobDataMap().put(ColorJob.EXECUTION_COUNT, 1); //或在创建JobDetail对象时使用.usingJobData("Key","Value").build(); //在Job的实现类的execute(JobExecutionContext context)中,FAVORITE_COLOR为该类的字符串常量 JobDataMap data = context.getJobDetail().getJobDataMap(); String favoriteColor = data.getString(FAVORITE_COLOR); data.put(EXECUTION_COUNT, ++count);
2.3 Trigger类的一些方法
2.31 创建Trigger对象及设置基本属性
Trigger trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(Date runTime).build(); SimpleTrigger trigger = (SimpleTrigger) org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(Date startTime).build(); CronTrigger trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(org.quartz.CronScheduleBuilder.cronSchedule("0/20 * * * * ?")) .build();
2.32 创建Trigger对象时设置定时信息
//withIntervalInSeconds(10)间隔时间为10秒,withRepeatCount(10)重复次数为10次,共执行11次 SimpleTrigger trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger3", "group1") .startAt(Date startTime).withSchedule(org.quartz.SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(10).withRepeatCount(10)).build(); //只执行一次futureDate(5,IntervalUnit.MINUTE)在5分钟之后 startAt(futureDate(5, IntervalUnit.MINUTE)) //时间间隔为40秒(withIntervalInMinutes(5)间隔5分钟)且没有重复执行次数限制 org.quartz.SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(40).repeatForever()
2.33 创建Trigger对象时绑定job
trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger3","group2").startAt(Date startTime).forJob(JobDetail job).build(); //绑定到Scheduler对象上:sched.scheduleJob(trigger);
2.34 获取Trigger对象的信息的方法
方法 | 说明 |
---|---|
trigger.getRepeatCount() | 获得该trigger的执行次数 |
trigger.getRepeatInterval() | 获得该trigger重复间隔时长的毫秒数 |
trigger.getCronExpression() | 获取trigger(CronTrigger)设置的时间表达式 |
2.4 JobExecutionContext类的一些方法
该类通过实现Job接口,复写其public void execute(JobExecutionContext context) throws JobExecutionException方法后得到
2.41 获取当前JobDetail的jobKey
JobKey jobKey = context.getJobDetail().getKey();
2.42
2.5 一些时间表达式例子
设置trigger的时间表达式: CronTrigger trigger = org.quartz.TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").withSchedule(org.quartz.CronScheduleBuilder.cronSchedule("0/20 * * * * ?")) .build();
时间表达式 | 说明 |
---|---|
0/20 * * * * ? | 每间隔20秒执行一次 |
15 0/2 * * * ? | 在每2分钟的第15秒执行 |
0 0/2 8-17 * * ? | 只在8am-5pm这段时间每2分钟执行一次 |
0 0/3 17-23 * * ? | 只在5pm-11pm这段时间每3分钟执行一次 |
0 0 10am 1,15 * ? | 在每个月的1号和15号早上10点执行 |
0,30 * * ? * MON-FRI | 在星期一至星期五期间每30秒执行一次 |
0,30 * * ? * SAT,SUN | 在星期六至星期日期间每30秒执行一次 |
3. web项目的定时任务
第一步:在web.xml文件里,设置web项目启动时初始化的Servlet,使项目启动时能够调用实现定时任务业务逻辑的类。
**(1) web.xml中的设置**
<servlet> <display-name>QuartzTestServlet</display-name> <servlet-name>QuartzTestServlet</servlet-name> <servlet-class>package.QuartzTestServlet</servlet-class> <!-- 当load-on-startup值为负整数或者未指定时,容器在该servlet被调用时加载 --> <!-- 当其值为0和正整数时,容器启动时加载,值越小,优先级越高 --> <load-on-startup>2</load-on-startup> </servlet> <!-- 可选,根据实际情况选择时候设置servlet-mapping --> <servlet-mapping> <servlet-name>QuartzTestServlet</servlet-name> <url-pattern>/QuartzTestServlet</url-pattern> </servlet-mapping>
**(2)package.QuartzTestServlet类需要继承javax.servlet.http.HttpServlet类,并复写public void init()方法。该方法中主要是调用具体设置调度定时作业、添加删除定时作业的类,还可以进行是否启动定时任务的判定、日志输出等。**
import org.apache.log4j.Logger; public class QuartzTestServlet extends HttpServlet{ private static final long serialVersionUID = 5148765487841631133L; //org.apache.log4j.Logger用于日志输出信息 private static final Logger log=Logger.getLogger(QuartzTestServlet.class); @Override public void init(){ log.info("QuartzTestServlet#init() is run.........."); try { //QuartzTestManager自己写的类用于实现添加定时任务的业务逻辑 QuartzTestManager.getInstance().run(); } catch (SchedulerException e) { e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("错误~~~~~~~~~~"); } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doPost(req, resp); } }
第二步:编写QuartzTestManager实现定时任务调度的业务逻辑。
public class QuartzTestManager { private static final Logger log=Logger.getLogger(QuartzTest.class); private static final String JOB_GROUP_NAME = "quartzTestJobs"; private static final String TRIGGER_GROUP_NAME = "quartzTestTriggers"; private static final String POSTFIX_JOB = "_Job"; private static final String POSTFIX_TRIGGER = "_Trigger"; //静态的任务作业周期,方便其他类使用 static String quartzTestJobCycle=""; //存储该类的实例,Job类通过getInstance()方法得到,算简单的单例模式吧,虽然没有私有的构造方法 private static QuartzTestManagerr instance; private Scheduler scheduler; public void run(){ try { log.info("~~~~~~QuartzTest定时任务调度开始~~~~~~~~"); JobDataMap quartzTestJob = new JobDataMap(); //ReadPropertiesUtil.getCycleName()方法是从properties配置文件中拿到输入参数的值,具体实现在最后说明 String quartzTestJobTime = ReadPropertiesUtil.getCycleName("SCHEDULER_MODELCHANGEIMPACTHISTORY_TIME"); if(!StringUtils.isEmpty(quartzTestJobTime)){ //根据设置的格式判断按月、按日或按小时等时间周期调度 String[] arr = quartzTestJobTime.split("_"); if(arr.length>1) { quartzTestJobCycle = "month"; } else { arr = quartzTestJobTime.split(":"); if(arr.length==3){ quartzTestJobCycle = "day"; }else if(arr.length==2){ quartzTestJobCycle = "hour"; } } if(!StringUtils.isEmpty(quartzTestJobCycle)){ try{ String conExpress = getConExpree(quartzTestJobCycle, quartzTestJobTime); if (existJob("quartzTest")) { removeJob("quartzTest"); addJob("quartzTest", QuartzTestJob.class, conExpress,quartzTestJob); } else { addJob("quartzTest", QuartzTestJob.class, conExpress,quartzTestJob); } log.info("~~~~~~~~~~~~~~~~~~~~定时任务调度设置成功~~~~~~~~~~~~~~~~~~~~~~~~"); }catch(Exception e){ log.info("~~~~~~~~~~~~~~~~~~~~定时任务调度设置错误~~~~~~~~~~~~~~~~~~~~~~~~"); } } } } catch (Exception e) { e.printStackTrace(); } } /** * 新增作业 * * @param name * 作业名称 * @param jobClass * 作业执行类class * @param cronExpression * cron表达式 * @throws MOAppException */ @SuppressWarnings({"unchecked" }) public static synchronized void addJob(String name, Class jobClass, String cronExpression, JobDataMap dataMap){ String jobName = name + POSTFIX_JOB; String triggerName = name + POSTFIX_TRIGGER; try { getInstance().registerJob(jobName, JOB_GROUP_NAME, triggerName, TRIGGER_GROUP_NAME, jobClass, cronExpression, dataMap); } catch (Exception e) { e.printStackTrace(); } } /** * 判断指定作业是否存在 * * @param name * 作业名称 * @throws MOAppException */ public static synchronized boolean existJob(String name) { String jobName = name + POSTFIX_JOB; try { JobDetail jobDetail = getInstance().scheduler.getJobDetail(jobName, JOB_GROUP_NAME); return (jobDetail != null); } catch (Exception e) { e.printStackTrace(); return false; } } public static synchronized ModelChangeImpactManager getInstance() throws SchedulerException { if (instance == null) { instance = new ModelChangeImpactManager(); instance.scheduler = new StdSchedulerFactory().getScheduler(); instance.scheduler.start(); } return instance; } /** * 删除作业 * * @param name * 作业名称 * @throws MOAppException */ public static synchronized void removeJob(String name) throws SchedulerException { if (existJob(name)) { try { String jobName = name + POSTFIX_JOB; String triggerName = name + POSTFIX_TRIGGER; Scheduler scheduler = getInstance().scheduler; scheduler.deleteJob(jobName, JOB_GROUP_NAME); scheduler.deleteCalendar(triggerName); } catch (Exception e) { e.printStackTrace(); } } } private static String getConExpree(String cycle, String runTime) { if(StringUtils.isEmpty(runTime)){ return null; } String con = ""; if (cycle.equals("once")) { String[] arr = runTime.split(" "); String[] day = arr[0].split("-"); String[] time = arr[1].split(":"); con = "0 " + time[1] + " " + time[0] + " " + day[2] + " " + day[1] + " ?"; } if (cycle.equals("hour")) { String[] arr = runTime.split(":"); con = arr[1] + " "+ arr[0] + " * ? * *"; } if (cycle.equals("day")) { String[] arr = runTime.split(":"); con = arr[2] + " " + arr[1] + " " + arr[0] + " ? * * "; } if (cycle.equals("month")) { String[] arr = runTime.split("_"); String[] time = arr[1].split(":"); con = time[2] + " " + time[1] + " " + time[0] + " " + arr[0] + " * ? "; } System.out.println(con); return con; } @SuppressWarnings({"unchecked" }) private synchronized void registerJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cronExpression, JobDataMap dataMap) throws SchedulerException, ParseException { JobDetail jobDetail = new JobDetail(jobName, jobGroupName, jobClass); jobDetail.setJobDataMap(dataMap); CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName); trigger.setCronExpression(cronExpression); scheduler.scheduleJob(jobDetail, trigger); if (!scheduler.isShutdown()) { scheduler.start(); } } }
第三步:编写定时任务具体需要执行功能的业务逻辑类,需要实现 org.quartz.Job接口并复写其public void execute(JobExecutionContext arg0)方法。在该方法中实现任务具体的业务逻辑
public class QuartzTestJob implements Job{ public void execute(JobExecutionContext arg0) throws JobExecutionException { ....... } }
附:ReadPropertiesUtil(读取properties文件参数值)
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; public class ReadPropertiesTest { private static final String PROPERTIES_NAME = "ReadPropertiesTest.properties"; private static Properties properties = null; static { reload(); } public static Properties getProperties(){ return properties; } public static void reload() { try{ properties = new Properties(); //直接获取该类同文件夹下的properties文件的输入流 // InputStream fi =ReadPropertiesTest.class.getResourceAsStream(PROPERTIES_NAME) ; //获取该properties文件的路径后创建inputstream输入流 String path = ReadPropertiesTest.class.getResource(PROPERTIES_NAME).getPath(); InputStream fi = getClassPathResourceAsStream(path); //java.util.Properties类中的方法传入输入流获取数据 properties.load(fi); }catch(Exception e){ e.printStackTrace(); } } private static InputStream getClassPathResourceAsStream(String name) throws IOException{ //return Thread.currentThread().getContextClassLoader().getResourceAsStream(name); return new BufferedInputStream(new FileInputStream(name)); } /** * 获取properties文件参数的MAP集合 * @return */ @SuppressWarnings("rawtypes") public static List<Map<String,Object>> getRuleCycleMap() throws Exception{ List<Map<String,Object>> list = new LinkedList<Map<String,Object>>(); Enumeration en = properties.keys(); while(en.hasMoreElements()){ Map<String,Object> map = new HashMap<String,Object>(); String key = en.nextElement().toString(); String value = properties.getProperty(key); map.put("id", key); //字符串转换编码方式,一边properties里显示的是中文转换后的编码就不用转换,如果直接显示的中文需要转换 map.put("name", new String(value.getBytes("ISO8859-1"), "UTF-8")); list.add(map); } return list; }
(1)简单实现读取properties文件的参数值
public static void main(String[] args){ //简单的获取参数方法 Properties properties = new Properties(); //注意1:ReadPropertiesTest.properties需要在该类的同文件夹下,才能通过下面的方法得到输入流 InputStream fi =ReadPropertiesTest.class.getResourceAsStream("ReadPropertiesTest.properties"); try { properties.load(fi); Enumeration en = properties.keys(); while(en.hasMoreElements()){ String key = en.nextElement().toString(); String value1 = properties.getProperty(key); //注意2:如果中文显示乱码可以用一下方式转换字符串编码 String value2 = new String(value1.getBytes("ISO8859-1"), "UTF-8"); System.out.println(key+":"+value1); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
相关文章推荐
- java读取properties文件的简单代码
- java读取配置文件properties的方法(很多不会用框架s2sh的开发者,喜欢用此方法)
- java代码及xml文件读取properties属性文件的方法
- Spring MVC框架下在java代码中访问applicationContext.xml文件中配置的文件(可以用于读取配置文件内容)
- JAVA代码读取配置文件信息 *.properties
- jsp中写java代码读取放在src下的XX.properties文件的程序
- java 中简单读取Properties配置文件
- java读取文件和写入文件的简单代码
- Java读取文件的简单代码
- spring框架整合使用定时任务框架java quartz的示例代码配置
- 来段代码提提神-Java读取config.properties文件中的key=value
- 最简单的框架(配制文件config.properties)文件内容:className=java.util.ArrayList
- java简单读取properties文件
- spring框架整合使用定时任务框架java quartz的示例代码配置
- 软件开发工程师(JAVA)中级考试大纲-----四(四)Log4J的原理及配置;Log4J常用的API;在项目中应用日志框架Log4J关键类和接口介绍;Java properties配置文件log
- Java-流的简单使用:读取文件、写入文件(面试题:删除注释代码)
- Java-流的简单使用:读取文件、写入文件(面试题:删除注释代码)
- 用java代码实现从excel表格读取数据然后写入生成国际化配置文件properties
- java代码和spring框架读取xml和properties文件
- java代码如何读取properties文件