前段时间,工作中遇到了页面动态设置Quartz中的CronTrigger中的CronExpression值的问题,在google中搜索了相关主题文章,虽然能解决部分问题,但不是很理想;比如,在Scheduler第一次启动Job时,可以重复设置CronTrigger的表达式值,都不会出现问题;但在CronTrigger触发启动了Job后,再重复设置CronTrigger的CronExpression值,存在两种情况,一种情况是当Job已经运行完毕,调用Scheduler的reschedulerJob()方法时,如果CronExpresion的表达式值设置植,比如:0 19 30 * * ?(该表示式表示每天晚上9点半准时运行关联的Job),系统当前时间是:20:00(即晚上8点),Job会立马运行起来(很怪异);第二种情况是当业务需求要同时改变Trigger关联的Job时jobDataAsMap属性值,Spring容器中获取指定的Job实例,设置其中的JobDataAsMap,然后再设置CronTrigger的CronExpresion值,调用Scheduler的reschedulerJob()方法时会抛出java.util.Collections.UnmodifiableSetException,主要是Quartz中的Job实现中用到了个不能修改的Map对象;
为了克服以上两种缺陷,本人的做法是在Spring配置CronTrigger时,设置其属性singleton为false(低本版),其他bean默认;在设置CronTrigger的CronExpression时,从Spring容器中获取一个新的Trigger再设置其CronExpression表达式值;第二步从Spring获取Job实例,产生一个新的Map实例,当然使用(java.util.HashMap)了,然后在把必要的参数key和value压入Map中,再调用Job的setJobDataAsMap(java.util.Map)方法,这样就避免使用原来不能修改的HashMap,重新调用Scheduler的reschedulerJob()方法,至此,以上两个问题都避免了。
从以上考虑的方法中存在点不足就是消耗浪费过多资源,比如每次设置下Trigger的表达式值都会重新创建HashMap和Trigger对象。不知道大家有没有其他更好的解决办法呢?^_^