博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Quartz2.2.1开发问题
阅读量:6968 次
发布时间:2019-06-27

本文共 5337 字,大约阅读时间需要 17 分钟。

hot3.png

一、org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean报 java.io.NotSerializableException异常,需要自己实现QuartzJobBean。

二、dao必须要实现序列化接口,Hibernate dao不能直接继承自HibernateDaoSupport,因为HibernateDaoSupport没有实现序列化接口,只能通过SessionFactory构造HibernateTemplate。
三、当库里己存在Trigger,应用启动时会从库里加载己存在Trigger,会报java.io.InvalidObjectException: Could not find a SessionFactory named: null等SessionFactory等相关异常。因为应用每次启动的得到的SessionFactory实例是不一样的,当从库里取到的Job进行反序列化时,Job里包含的SessionFactory与当前的SessionFactory不一致,所以为null

四、一旦QuartzJobBean类或里面的属性被修改,那么数据库中对应的qrtz_job_details保存的job_class_name还是以前的QuartzJobBean,这导致这个旧的job再一次重新执行时,会找不到相应的QuartzJobBean,而报空指针异常。


第二个问题与第三个是互相关联的,我想到要解决这两个问题的一个方案是Job中不要包含SessionFactory就没一切OK了, 因为SessionFactory是hibernate dao的属性,而hibernate dao是SimpleService的属性,因此SimpleService不能有任何hibernate dao属性了。如此SimpleService业务方法里需要的hibernate dao又如何获取呢?对 spring 的了解,我们知道可以通过ApplicationContext获取到任何spring bean,但是在这里ApplicationContext又怎么获取呢? ... 查看org.springframework.web.context.ContextLoaderListener找到org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext()可以获取到ApplicationContext,增加一个SpringBeanService类,实现序列化接口,通过SpringBeanService可以获取到web己经加载的spring bean

package com.sundoctor.example.service;
import java.io.Serializable;
import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Service;import org.springframework.web.context.ContextLoader;
@SuppressWarnings("unchecked")@Service("springBeanService")public class SpringBeanService implements Serializable{
 private static final long serialVersionUID = -2228376078979553838L;
 public 
 T getBean(Class
 clazz,String beanName){  ApplicationContext context = ContextLoader.getCurrentWebApplicationContext();  return (T)context.getBean(beanName); }}

因为Hibernate Dao不再持久到Job中,所在不再需要实现序列化接口,可以继承HibernateDaoSupport,当然也可以不继承,可以根据自己喜好的方式编写,不再有任何限制

package com.sundoctor.example.dao;
import org.hibernate.Session;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.orm.hibernate3.HibernateCallback;import org.springframework.orm.hibernate3.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;
import com.sundoctor.example.model.Customer;import com.sundoctor.example.service.CustomerService;
@Repository("customerDao")public class CustomerHibernateDao extends HibernateDaoSupport {
 private static final Logger logger = LoggerFactory.getLogger(CustomerService.class);
 public Customer getCustomer2() {   return (Customer) this.getHibernateTemplate().execute(new HibernateCallback() {   public Object doInHibernate(Session session) {    Customer customer = (Customer) session.createQuery("from Customer where id = 1").uniqueResult();    logger.info("Customer2={}", customer);    return customer;   }  }); }
 public Customer getCustomer1() {    Customer customer = (Customer) this.getHibernateTemplate().get(Customer.class, 1);  logger.info("Customer1={}", customer);  return customer; }
}

因为hibernate dao 不再实现序列化接口和继承自HibernateDaoSupport,不能再注入到业务类中了。在业务类中注入以上的SpringBeanService,业务方法需要的hibernate dao通过以上的SpringBeanService.getBean获取

package com.sundoctor.example.service;
import java.io.Serializable;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;
import com.sundoctor.example.dao.CustomerHibernateDao;import com.sundoctor.example.model.Customer;
@Service("customerService")public class CustomerService implements Serializable {
 private static final long serialVersionUID = -6857596724821490041L; private static final Logger logger = LoggerFactory.getLogger(CustomerService.class); private SpringBeanService springBeanService;
 @Autowired public void setSpringBeanService(@Qualifier("springBeanService") SpringBeanService springBeanService) {  this.springBeanService = springBeanService; }
 public void testMethod1() {  // 这里执行定时调度业务    CustomerHibernateDao customerDao =springBeanService.getBean(CustomerHibernateDao.class,"customerDao");  Customer customer = customerDao.getCustomer1();  logger.info("AAAA:{}", customer);
 }
 public void testMethod2() {  // 这里执行定时调度业务  CustomerHibernateDao customerDao =springBeanService.getBean(CustomerHibernateDao.class,"customerDao");  Customer customer = customerDao.getCustomer2();  logger.info("BBBB:{}", customer); }

customerService是我们的Job具体执行的类,它必须实现序列化,因为它会被序列化到表qrtz_job_details中的job_class_name字段中,所以springBeanService属性也必须序列化,这里其实也可以不用写springbeanservice,而是直接在testMethod中使用applicationContext.getBean去拿到dao,然后进行业务操作。

如果当任务执行的时间点上,正好服务器down掉或由于其他原因任务没有顺利完成

该如何自动或手动唤醒它,让他顺利执行呢?

//获取到SchedulerScheduler scheduler = ...;//(Scheduler)springContext.getBean("quartzScheduler");//通过trigger name和trigger group得到SimpleTrigger SimpleTrigger trigger = (SimpleTrigger)scheduler.getTrigger("52f071d3-eebb-4308-abeb-9ce8ec58aba4", "DEFAULT");//重新设置Trigger己经触发的次数int timesTriggered = trigger.getTimesTriggered();trigger.setTimesTriggered(timesTriggered > 0 ? timesTriggered -1 : 0);
//可选,重新设置开始触发时间//trigger.setStartTime(startTime);//可选,重新设置下次触发时间//trigger.setNextFireTime(nextFireTime);//等等,还有许多可选配置可以重新设置
//调用rescheduleJob重新调度tirggerscheduler.rescheduleJob(trigger.getName(), trigger.getGroup(), trigger);

 

转载于:https://my.oschina.net/javayan/blog/607042

你可能感兴趣的文章
js数字比较【牢记】
查看>>
如何实现密码域灰色默认提示?
查看>>
zabbix
查看>>
JAVA--虚函数,抽象函数,抽象类,接口
查看>>
解决 You could try using --skip-broken to work around the problem
查看>>
php清楚squid缓存
查看>>
openstack Folsom版本安装
查看>>
Cisco Catalyst 交换机一直处于rommon模式无法启动IOS问题的解决
查看>>
java io以及unix io模型
查看>>
syslog及syslog-ng详解
查看>>
UITableViewController
查看>>
我的友情链接
查看>>
Java源码分析系列之HttpServletRequest源码分析
查看>>
如何通过命令行创建和设置一个MySQL用户
查看>>
WPF DrawingContext Pen
查看>>
Wordpress+LNMP 环境搭建
查看>>
小步快跑是这样玩的(下)
查看>>
rsync工作方式介绍03
查看>>
Windows 7蓝屏自动重启,无法修复的处理办法
查看>>
SSH-Struts2、Spring和Hibernate应用实例
查看>>