任务管理模块 quartz + spring
2011-12-18 20:33
162 查看
任务管理模块的需求:实现对任务的crud操作,定时执行,以及执行结果的查看。由于涉及到CRUD操作,因此持久化是必须的。关于quartz持久化的配置,有很多文章可以参考,这里就不说了,本文主要谈谈持久化实现和其中一些很少有人提及的问题。
1. CRUD操作的实现
对于用ssh框架习惯的人来说,一提到CRUD,hibernate就是当仁不让的选择。笔者想说的是quartz已经完成的事情,为啥你非得再去做一次呢? 事实上只要配置好quartz的store,scheduler一操作jobdetail或trigger,scheduler的内存变化就会反映到数据库里。因此,CUD的操作,通过scheduler进行即可。这里比较麻烦的是R的操作该怎么处理。有两种选择: 1.仍然用scheduler,通过一系列的get****方法去取得jobdetail和trigger的信息,封装后再传到页面;2.使用jdbcTemplate或者hsql直接查询数据库。
第一种方法比较简单,但实现相对繁琐;第二种虽然很容易,但又涉及到一个问题:如何读取blob字段?blob字段对于jobdetail来说存放的是jobdatamap的数据,所以读取blob字段是跳不过的一环。既然,quartz已经实现了持久化,当然这个问题也解决了,因此将quartz的类拿来修改下就可以了,不过quartz是通过resultset来实现的,所以最后笔者选择了jdbc这个最原始的东东。
DriverManagerDataSource dd =(DriverManagerDataSource)webContext.getBean("dataSource1");
blob的处理可以参考quartz中org.quartz.impl.jdbcjobstore.StdJDBCDelegate的源代码,这里将主要的方法提取出来:
public class BlobDataDelagte {
public Object getObjectFromBlob(ResultSet rs, String colName)
throws ClassNotFoundException, IOException, SQLException {
Object obj = null;
Blob blobLocator = rs.getBlob(colName);
if (blobLocator != null && blobLocator.length() != 0) {
InputStream binaryInput = blobLocator.getBinaryStream();
if (null != binaryInput) {
if (binaryInput instanceof ByteArrayInputStream
&& ((ByteArrayInputStream) binaryInput).available() == 0 ) {
//do nothing
} else {
ObjectInputStream in = new ObjectInputStream(binaryInput);
try {
obj = in.readObject();
} finally {
in.close();<
4000
br />
}
}
}
}
return obj;
}
protected Object getJobDataFromBlob(ResultSet rs, String colName)
throws ClassNotFoundException, IOException, SQLException {
if (true) {
Blob blobLocator = rs.getBlob(colName);
if (blobLocator != null) {
InputStream binaryInput = blobLocator.getBinaryStream();
return binaryInput;
} else {
return null;
}
}
return getObjectFromBlob(rs, colName);
}
protected Map<?, ?> convertFromProperty(Properties properties) throws IOException {
return new HashMap<Object, Object>(properties);
}
public Map<?, ?> getMapFromProperties(ResultSet rs, String colName)
throws ClassNotFoundException, IOException, SQLException {
Map<?, ?> map;
InputStream is = (InputStream) getJobDataFromBlob(rs, colName);
if(is == null) {
return null;
}
Properties properties = new Properties();
if (is != null) {
try {
properties.load(is);
} finally {
is.close();
}
}
map = convertFromProperty(properties);
return map;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
调用方法如下:
Map<?, ?> map = (Map<?, ?>) new BlobDataDelagte().getObjectFromBlob(rs, "JOB_DATA");
String tbean =(String)map.get("targetBean");
2. quartz调度 非JOBDETAIL类
quartz调度非JOBDETAIL类,在很多文章都有提及,使用spring的org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean类封装下就可以了。但是
一涉及到quartz持久化的时候,这个类会抛异常:
Caused by: java.io.NotSerializableException: Unable to serialize JobDataMap for insertion into database because the value of property 'methodInvoker' is not serializable: org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
这个异常的意思就是MethodInvokingJobDetailFactoryBean不支持持久化功能。解决办法:
到 http://jira.springframework.org/browse/SPR-3797 下载两个文件:
frameworkx.springframework.scheduling.quartz.BeanInvokingJobDetailFactoryBean
frameworkx.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
这两个class有着不同的应用,对于BeanInvokingJobDetailFactoryBean来说,它可以触发非静态的方法;
而MethodInvokingJobDetailFactoryBean可以触发静态和非静态方法。由于这两个类都是用来改进MethodInvokingJobDetailFactoryBean的,因此对要调用的javabean的查找都是通过applicationContext进行的,因此在使用过程中需要做些修正,在applicationContext找不到javabean的情况下,需要通过反射机制来创建javabean。
Object bean =null;
try
{
bean = applicationContext.getBean(targetBean);
}
catch(Exception e)
{
if (bean==null)
{
bean =Class.forName(targetBean).newInstance();
}
}
3.执行结果的查看
对于用户来说,一个很好的体验就是能够跟踪和了解任务的执行情况和结果。这个属于quartz的题外话,quartz 自身并不提供查看执行结果的功能。若要实现,需要自己处理,这里需要考量两个问题:对于像邮件通知、短信提醒这样的类要怎么提供自身的执行情况和进度?对于数据库存储过程要怎么提供自身的执行情况和进度? 一个最简单的办法就是在数据库建这样的表,然后相关任务类、存储过程不断对这个表进行添加和更新操作,在页面上通过轮询来获取 任务的执行情况和结果。这里只简单的用ORACLE的查询结果进行展示:
4. XML的持久化数据
使用spring的人都很熟悉怎么使用XML配置各类javabean,但是很少有人会提及将spring容器内的javabean的最新变动存回xml,quartz的数据虽然已经持久化在数据表里了,但是还是有必要将变动情况也存放在XML文件里,毕竟大家都晓得:“不要把所有鸡蛋都放在同一个篮子里”。对于XML的读写,有很多文章可以借鉴,这里不详述了,只是提供个思路,仅供参考。
相关文章推荐
- Spring Boot集成持久化Quartz定时任务管理和界面展示
- Quartz动态管理一次性定时任务(Spring)
- Quartz+Spring Boot实现动态管理定时任务
- Quartz+Spring 实现定时任务的 管理和监控
- Spring Boot集成持久化Quartz定时任务管理和界面展示
- Spring+quartz 实现动态管理任务
- Spring Boot集成持久化Quartz定时任务管理和界面展示(转)
- Cube-web系统之Quartz+Spring实现任务监控管理
- 定时任务管理系统(spring boot + quartz + angular)
- Spring中bean的管理,以及定时任务quartz
- SpringBoot学习-持久化Quartz定时任务管理
- Spring+Quartz 实现任务动态管理监控
- spring整合quartz,实现自助动态管理自动任务
- Quartz学习笔记(七) quartz与spring实现任务动态管理面板
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- [置顶] spring整合quartz实现动态定时任务的前台网页配置与管理
- Spring 动态管理定时任务(使用quartz) 只是管理启动时间 不能做启动和暂停
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码
- Spring Boot集成持久化Quartz定时任务管理和界面展示
- Spring动态对Quartz定时任务的管理,实现动态加载,停止的配置实例代码