Java定时任务4:Jcrontab使用数据库存储数据源

本文将要介绍自己项目中如何使用本地数据表存储数据源并执行定时任务,同时实现将配置文件中的绝对路径改为相对路径。原理大致相同,参考的底层代码。

1.自定义一个Servlet来替换org.jcrontab.web.loadCrontabServlet加载JCrontab(方法就是仿照loadCrontabServlet)

public class ServletJcrontab extends HttpServlet {

	private static final long serialVersionUID = 4105652442492674804L;
	private Crontab crontab = null;

	/**
	 * 初始化方法
	 */
	public void init() throws ServletException {

		System.out.print("Working?...");
		process();
		System.out.println("OK");
	}

	/**
	 * 加载属性文件并启动定时任务
	 */
	@SuppressWarnings("unchecked")
	public void process() {

		String propz = "/WEB-INF/classes/crontab/jcrontab.properties";

		String props = getServletConfig().getInitParameter("PROPERTIES_FILE");
		if (props == null) {
			props = propz;
		}
		props = this.getServletContext().getRealPath(props);

		Properties propObj = new Properties();
		try {
			InputStream input = createPropertiesStream(props);
			propObj.load(input);
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}

		ServletConfig c = getServletConfig();
		Enumeration keys = c.getInitParameterNames();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			propObj.setProperty(key, c.getInitParameter(key));
		}

		String log4jpath = propObj.getProperty("org.jcrontab.log.log4J.Properties");
		if (log4jpath != null) {
			log4jpath = this.getServletContext().getRealPath(log4jpath);
			propObj.setProperty("org.jcrontab.log.log4J.Properties", log4jpath);
		}

		String jcrontabconfig = propObj.getProperty("org.jcrontab.config");
		if (jcrontabconfig != null) {
			jcrontabconfig = this.getServletContext().getRealPath(jcrontabconfig);
			propObj.setProperty("org.jcrontab.config", jcrontabconfig);
		}

		String datafile = propObj.getProperty("org.jcrontab.data.file");
		if (datafile != null) {
			datafile = this.getServletContext().getRealPath(datafile);
			propObj.setProperty("org.jcrontab.data.file", datafile);
		}

		crontab = Crontab.getInstance();

		try {
			ShutdownHook();
			crontab.init(propObj);

		} catch (Exception e) {
			Log.error(e.toString(), e);
		}
	}

	/*
	 * 关闭定时任务
	 */
	public void ShutdownHook() throws Exception {

		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				doStop();
			}
		});
	}

	public void destroy() {

		doStop();
	}

	public void doStop() {

		Log.info("Shutting down...");
		crontab.uninit(100);
		Log.info("Stoped");
	}

	protected InputStream createPropertiesStream(String name)
			throws IOException {

		return new FileInputStream(name);
	}
}

2.web.xml文件配置

	<servlet>
		<servlet-name>ServletJcrontab</servlet-name>
		<servlet-class>com.kang.timerandcron.cron.ServletJcrontab</servlet-class>
		<load-on-startup>200</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>ServletJcrontab</servlet-name>
		<url-pattern>/Startup</url-pattern>
	</servlet-mapping>

3.持久化文件,作用是从数据表中读取数据源

public class JcrontabSQLSource implements DataSource {

	private CrontabParser cp = new CrontabParser();
	private Environment env;
	private static JcrontabSQLSource instance;

	public JcrontabSQLSource() {
		env = Environment.getEnv();
	}

	public DataSource getInstance() {

		if (instance == null) {
			instance = new JcrontabSQLSource();
		}
		return instance;
	}

	public CrontabEntryBean find(CrontabEntryBean ceb)
			throws CrontabEntryException, ClassNotFoundException, SQLException,
			DataNotFoundException {
		
		CrontabEntryBean[] cebra = findAll();
		for (int i = 0; i < cebra.length; i++) {
			if (cebra[i].equals(ceb)) {
				return cebra[i];
			}
		}
		throw new DataNotFoundException("Unable to find :" + ceb);
	}

	/**
	 * 底层会调用findAll方法加载数据源
	 */
	@SuppressWarnings("unchecked")
	public CrontabEntryBean[] findAll() throws CrontabEntryException,
			ClassNotFoundException, SQLException, DataNotFoundException {
		
		String nodeType = Crontab.getInstance().getProperty("org.jcrontab.data.nodetype");
		
		Vector list = new Vector();
		// 从指定的表中读取数据源
		String queryAll = " SELECT id,second,minute,hour,dayofmonth,month,dayofweek, "
				+ " year, task, extrainfo FROM T_DWK_CRONTABEVENTS "
				+ " where nodetype = " + nodeType + " and startOrClose = 1 ";
		
		Connection conn = null;
		java.sql.Statement st = null;
		java.sql.ResultSet rs = null;
		try {
			conn = env.getConnection();
			st = conn.createStatement();
			rs = st.executeQuery(queryAll);
			if (rs != null) {
				while (rs.next()) {
					boolean[] bSeconds = new boolean[60];
					boolean[] bYears = new boolean[2500];
					int id = rs.getInt("id");
					String second = rs.getString("second");
					String minute = rs.getString("minute");
					String hour = rs.getString("hour");
					String dayofmonth = rs.getString("dayofmonth");
					String month = rs.getString("month");
					String dayofweek = rs.getString("dayofweek");
					String year = rs.getString("year");
					String task = rs.getString("task");
					String extrainfo = rs.getString("extrainfo");
					String line = minute + " " + hour + " " + dayofmonth + " "
							+ month + " " + dayofweek + " " + task + " "
							+ extrainfo;

					CrontabEntryBean ceb = cp.marshall(line);
					cp.parseToken(year, bYears, false);
					ceb.setId(id);
					ceb.setBYears(bYears);
					ceb.setYears(year);

					cp.parseToken(second, bSeconds, false);
					ceb.setBSeconds(bSeconds);
					ceb.setSeconds(second);
					ceb.setBusinessDays(true);

					list.add(ceb);
				}
				rs.close();
			} else {
				throw new DataNotFoundException("定时任务底层sql出错了 ");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				conn.close();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
		}
		
		CrontabEntryBean[] result = new CrontabEntryBean[list.size()];
		for (int i = 0; i < list.size(); i++) {
			result[i] = (CrontabEntryBean) list.get(i);
		}
		
		return result;
	}

	public void remove(CrontabEntryBean[] arg0) throws Exception {
		// TODO Auto-generated method stub
	}

	public void store(CrontabEntryBean[] arg0) throws Exception {
		// TODO Auto-generated method stub
	}
}

4.jcrontab.properties

#端口号(查询条件)
org.jcrontab.data.nodetype=6666
#指定持久化文件为Java类,会自动调用里面的findAll()方法
org.jcrontab.data.datasource = com.kang.timerandcron.cron.JcrontabSQLSource
org.jcrontab.Crontab.refreshFrequency = 3
org.jcrontab.log.Logger=org.jcrontab.log.Log4JLogger
org.jcrontab.log.log4J.Properties=WEB-INF/classes/log4j.properties

5.自定义的两个定时任务

public class CrontabMainTest {

	public static void main(String[] args) {

		System.out.println(new Date());
		System.out.print("调用main方法   ");
		if (args.length > 0 && args != null) {
			for (String str : args) {
				System.out.print(str + " ");
			}
			System.out.println();
		}
	}
}
/**
 * 需要实现Runnable接口,可以接收参数
 * @author kang
 *
 */
public class CrontabRunTest implements Runnable {

	private String[] args;

	public CrontabRunTest(String[] args) {

		this.args = args;
	}

	public void run() {

		System.out.println(new Date());
		System.out.print("调用run方法   ");
		if (args.length > 0 && args != null) {
			for (String str : args) {
				System.out.print(str + " ");
			}
			System.out.println();
		}
	}
}

6.相关sql语句

--创建表
create table T_DWK_CRONTABEVENTS
(
  id             NUMBER(10) primary key not null,
  nodetype       NUMBER(4) default 33,
  title          VARCHAR2(255),
  second         VARCHAR2(64) default '0',
  minute         VARCHAR2(256) default '*',
  hour           VARCHAR2(64) default '*',
  dayofmonth     VARCHAR2(64) default '*',
  month          VARCHAR2(64) default '*',
  dayofweek      VARCHAR2(64) default '*',
  year           VARCHAR2(64) default '*',
  task           VARCHAR2(255),
  extrainfo      VARCHAR2(512),
  startorclose   NUMBER(2) default 1,
  createtime     DATE default sysdate
);
comment on table T_DWK_CRONTABEVENTS
  is '定时任务表';
-- Add comments to the columns 
comment on column T_DWK_CRONTABEVENTS.id
  is '主键id';
comment on column T_DWK_CRONTABEVENTS.nodetype
  is '节点';
comment on column T_DWK_CRONTABEVENTS.title
  is '定时任务名';
comment on column T_DWK_CRONTABEVENTS.second
  is '秒';
comment on column T_DWK_CRONTABEVENTS.minute
  is '分';
comment on column T_DWK_CRONTABEVENTS.hour
  is '小时';
comment on column T_DWK_CRONTABEVENTS.dayofmonth
  is '日';
comment on column T_DWK_CRONTABEVENTS.month
  is '月';
comment on column T_DWK_CRONTABEVENTS.dayofweek
  is '星期';
comment on column T_DWK_CRONTABEVENTS.year
  is '年';
comment on column T_DWK_CRONTABEVENTS.task
  is '类路径#方法名';
comment on column T_DWK_CRONTABEVENTS.extrainfo
  is '参数';
comment on column T_DWK_CRONTABEVENTS.startorclose
  is '开启活关闭';
comment on column T_DWK_CRONTABEVENTS.createtime
  is '创建时间';

/*  
--插入数据  */
insert into T_DWK_CRONTABEVENTS (id, nodetype, title, task, extrainfo)
values (1, '6666', 'dwk自己测试定时任务', 'com.kang.timerandcron.cron.process.CrontabRunTest#run', 'hello world')

insert into T_DWK_CRONTABEVENTS (id, nodetype, title, minute, task, extrainfo)
values (2, '6666', 'dwk自己测试定时任务', '*/2',  'com.kang.timerandcron.cron.process.CrontabMainTest#main', '')


备注:配置数据源和获取数据源的代码这里没有给出,大家可以根据需求自己编写

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值