使用线程实现“到点自动办理”

最近弄一功能,需要到点了自动办结日程。实现这个功能有两个办法,一个是使用线程,一个是使用数据库中的作业(SQL Server里面有作业,其他的数据库有木有不太清楚)。

基本思路是:在系统文件里配置俩变量:是否启动自动办结,自动办结时间。系统启动读取“是否自动办结”变量,若启动就开启一个线程。该线程不断获取当前时间,若当前时间与自动办结时间相同或在5分钟之内,就自动办结待办日程。

具体代码如下:

1、在配置文件中配置变量:

startAutoEnd:1 是否启动线程,设置为启动

autoEndTime:12:30 自动办结时间,这里设置为12点半(设置成12点也行)

2、系统启动时,添加代码是否启动线程:

Integer startAutoEnd=0;
if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
	startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
}
if(startAutoEnd==1){//说明开启自动办结
	Thread th = new Thread(new com.wjl.AutoEndThread(),"autoEnd");
	th.start();//启动线程
}
 

 3、AutoEndThread线程处理:

public class AutoEndThread implements Runnable {
	org.apache.log4j.Logger logger=Logger.getLogger(AutoEndThread.class);
	public void run() {
		autoEnd();
	}
	
	//日程记录自动办结
	private void autoEnd(){
		Integer startAutoEnd=0;
		String autoEndTime="";
		int hour=0,len=0,minite=0,sign=0,hour2=0,minite2=0;
		Calendar date = null;
		ExecSQL execSQL =null;
		StringBuffer sql =new StringBuffer();
		try {
			Thread.sleep(30000);//休眠半分钟,等待其他数据初始化完成
			execSQL = (ExecSQL) SpringApplicationContextHolder.getSpringBean("ExecSQL");//获取ExecSQL的bean
			while(true){
				//避免配置文件在项目启动过程中修改
				if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
					startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
				}
				if(startAutoEnd==1){//说明开启自动办结
					//获取系统设定的自动办结时间
					if(WebAppConfig.app("autoEndTime")!=null && !WebAppConfig.app("autoEndTime").equals("")){
						autoEndTime = WebAppConfig.app("autoEndTime");
					}
					
					if(autoEndTime!=null && !autoEndTime.equals("")){//说明有设置时间
						//变量初始化
						hour=0;
						len=0;
						minite=0;
						sign=0;
						sql.delete(0, sql.length());//清空StringBuffer
						
						//获取设置的时间
						len=autoEndTime.split(":").length;
						if(len<2){//说明没有冒号,那么只有时没有分
							autoEndTime = autoEndTime.replaceAll(":", "").replaceAll(":","");//替换冒号
							hour=Integer.parseInt(autoEndTime);
							minite=0;
						}else{
							hour = Integer.parseInt(autoEndTime.split(":")[0]);
							minite = Integer.parseInt(autoEndTime.split(":")[1]);
						}
						
						//获取当前时间
						date = Calendar.getInstance();
						hour2=date.get(Calendar.HOUR_OF_DAY);
						minite2= date.get(Calendar.MINUTE);
//						System.out.println(autoEndTime+"\n"+hour+"\n"+hour2+"\n"+minite+"\n"+minite2);
						if((hour==hour2 && minite==minite2) || ((hour==hour2 && (minite2>minite) && (minite2-minite)<=5))){//说明当前时间即为设置的处理时间(或者5分钟之内)
							sql.append("update S_TODOTASK set S_FINISH=1,S_FinishUserID=s.S_USER_ID,S_FinishDate=GETDATE(),S_FinishMemo='系统自动办结' ");
							sql.append("from  S_SCHEDULE s where s.S_ID = S_TODOTASK.S_TableKey ");
							sql.append("and S_TODOTASK.S_ModuleID=0 and S_TODOTASK.S_VALID=1 ");
							sql.append("and S_TODOTASK.S_FINISH=0 and S_TODOTASK.S_AUTOEND=1 "); 
							sql.append("and datediff(day,S_TODOTASK.S_PlannedDate,GETDATE())=0");
							
//							System.out.println("自动办结执行的SQL:"+sql.toString());
//							System.out.println("*******************************************************************************\n"+execSQL);
							sign = execSQL.execSQL(sql.toString());
							logger.debug("自动办结执行的SQL:"+sql.toString()+"\n执行结果:"+sign);
							Thread.sleep(30000);//休眠半分钟
						}
						
					}
				}
			}
			}catch (Exception e) {
				e.printStackTrace();
			}
	}
}
4、SpringApplicationContextHolder的getSpringBean()获取ExecSQL实例(ExecSQL实例需要在Spring的配置文件中进行配置):
public class SpringApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringApplicationContextHolder.context = context;
    }
    public static Object getSpringBean(String beanName) {
        return context==null?null:context.getBean(beanName);
    }
    public static String[] getBeanDefinitionNames() {
        return context.getBeanDefinitionNames();
    }
}
 

 5、ExecSQL中的execSQL方法用来执行SQL语句:

/***
 * 执行sql语句,insert、update、delete
 * 
 * @param sql
 * @return 1-成功,0-失败
 */
public int execSQL(final String sql) throws Exception{
	log.debug("执行sql语句: " + sql);
	try {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
			return session.createSQLQuery(sql).executeUpdate();
		}
	});
	} catch (Exception re) {
		log.info("执行sql:[" + sql + "]失败:" + re.getMessage());
		log.error("执行sql:[" + sql + "]失败:" + re.getMessage(), re);
		throw re;
	}
}

6、说明:

项目中的ExcelSQL实例是直接从Spring的实例中获取的,而不是直接New对象或者通过Spring重新注册获取,原因在于:

a、直接New:ExcelSQL对象不会为空,但是getHibernateTemplate()对象为空。

b、使用Spring注册ExcelSQL,ExcelSQL对象为空。

最后就剩下直接从Spring中取ExcelSQL实例了。

猜你喜欢

转载自1017401036.iteye.com/blog/2217228