公司一大牛写的一个自动任务框架

有一种人,徘徊在牛a和牛c之间。。。

 

 在工作中经常有业务是异步的:

1.用户办了一个订单,填写了一个反馈,当订单竣工的时候要发短信通知客户,说你办理的业务现在成功了

2.用户定购了一个账单,要每个月都要给用用户发送 上月用户账单内容到指定的 邮箱 或者 手机

3.有些统计的内容 需要每天计算 插到数据库里

 

等等,这都需要有个自动任务来管理,定时执行这些任务,并且统一管理。

 

公司一牛人写了一个自动任务的框架,可以定时帮助我们执行一些任务,并且由一张表(neb_trigger)统一管理,在工作中我们就是使用的 这个自动任务的框架 来完成 某些异步业务 或者定时任务的

 

 

我们项目的架构 是前台的action调用 后台的ejb ,因此自动任务 写在ejb里,大致的原理如下:

 

1.首先 自动任务(Trigger)维护着 一张表 (netb_trigger),她根据表中任务的信息,来执行业务方法(利用反射),表中有个字段是 业务方法的实现类的

 

2.定义了一个接口 TriggerTask ,只有一个方法 doTask(),何使用到自动任务的 业务都需要实现这个接口

 

3.Trigger 是一个会话bean ,其实现方法只有 一个业务方法 runTask(),它会调用 TriggerTask 接口中的runTask()方法 利用反射来执行 业务方法

 

4.为了对 netb_trigger 进行 添加,修改,删除 自动任务,又写了一个 TriggerManage类,这个类是用来供Action层来添加删除和修改自动任务的,其中有个方法

 public static String addTask(
   String taskDesc,
   String clazz,
   String inParam,
   String cycle,
   String cycleLimit,
   String dayLimit,
   String hourLimit) throws Exception

 

自动任务将 利用 传递的clazz 来 反射调用业务方法

 

目标:通过 一个main方法去 掉部署在jboss的ejb的自动任务,然他去定时执行执行业务方法

 

为了让大家能使用到这个自动任务框架 我一步一步 让这个自动任务跑起来!!flow me,let's go!!

 

首要条件:需要有jboss ,hibernate,mysql 环境

 

步骤1:建立 自动任务状态表,以及对应的实体

任务表:netb_trigger

Sql代码 复制代码
  1. CREATE TABLE `netb_trigger` (              
  2.                 `ID` char(255) NOT NULL,                 
  3.                 `TASKDESC` char(255) DEFAULT NULL,       
  4.                 `STATE` int(10) DEFAULT NULL,            
  5.                 `CLAZZ` char(255) DEFAULT NULL,          
  6.                 `INPARAM` char(255) DEFAULT NULL,        
  7.                 `CYCLE` char(255) DEFAULT NULL,          
  8.                 `CYCLELIMIT` char(255) DEFAULT NULL,     
  9.                 `DAYLIMIT` char(255) DEFAULT NULL,       
  10.                 `HOURLIMIT` char(255) DEFAULT NULL,      
  11.                 `CREATETIME` datetime DEFAULT NULL,      
  12.                 `LASTTIME` datetime DEFAULT NULL,        
  13.                 PRIMARY KEY (`ID`)                       
  14.               ) ENGINE=InnoDB DEFAULT CHARSET=gbk       
CREATE TABLE `netb_trigger` (           
                `ID` char(255) NOT NULL,              
                `TASKDESC` char(255) DEFAULT NULL,    
                `STATE` int(10) DEFAULT NULL,         
                `CLAZZ` char(255) DEFAULT NULL,       
                `INPARAM` char(255) DEFAULT NULL,     
                `CYCLE` char(255) DEFAULT NULL,       
                `CYCLELIMIT` char(255) DEFAULT NULL,  
                `DAYLIMIT` char(255) DEFAULT NULL,    
                `HOURLIMIT` char(255) DEFAULT NULL,   
                `CREATETIME` datetime DEFAULT NULL,   
                `LASTTIME` datetime DEFAULT NULL,     
                PRIMARY KEY (`ID`)                    
              ) ENGINE=InnoDB DEFAULT CHARSET=gbk     

 

 实体Tirgger

 

Java代码 复制代码
  1. package cn.com.xinli.netb.entitys;   
  2.   
  3. import java.io.Serializable;   
  4. import java.sql.Timestamp;   
  5.   
  6. /**  
  7.  *  触发任务表  
  8.  * @author diaoyf  
  9.  *  
  10.  */  
  11. public class Trigger implements Serializable   
  12. {   
  13.     public static final long serialVersionUID = 1;   
  14.        
  15.     /** id */  
  16.     private String id;   
  17.        
  18.     /** 触发任务描述 */  
  19.     private String taskDesc;   
  20.        
  21.     /** 触发状态 0:允许触发 1:取消触发 */  
  22.     private int state;   
  23.        
  24.     /**  
  25.      * 回调对象的包、类路径名  
  26.      * 触发管理器根据此包、类路径名,通过反射机制实例化对象  
  27.      */  
  28.     private String clazz;   
  29.     /** 回调方法输入参数 */  
  30.     private String inParam;   
  31.   
  32.     /**  
  33.      * 触发周期  
  34.      * <li>atonce 表示一次(由小时触发器管理)</li>  
  35.      * <li>min 表示每分</li>  
  36.      * <li>hour 表示每小时</li>  
  37.      * <li>day 表示每天</li>  
  38.      * <li>month 表示每月</li>  
  39.      * <li>3month 表示每季度</li>  
  40.      * <li>year 表示每年</li>  
  41.      */  
  42.     private String cycle;   
  43.        
  44.     /**  
  45.      *  触发时间限制  
  46.      *  格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间  
  47.      *  格式"-", 表示无触发时间限制  
  48.      *    
  49.      */  
  50.     private String cycleLimit;    
  51.     /**  
  52.      * 触发日期限制  
  53.      * 如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";  
  54.      * 如限制在每月10日,设置格式为"10-10";  
  55.      * 如果没有日期限制,设置格式为"-"  
  56.      * 如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日  
  57.      */  
  58.     private String dayLimit;    
  59.     /**  
  60.      * 触发时间限制,时间规则最小"00:00",最大"23:59"  
  61.      * 如邮件反馈限制在每天8~17时(8:00~17:59),hourLimit设置格式为"8:00-17:59";  
  62.      * 如限制在12时(12:00~12:59),设置格式为"12:00-12:59".  
  63.      * 如果没有时间限制,设置格式为"-"  
  64.      * 如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59  
  65.      */  
  66.     private String hourLimit;   
  67.        
  68.     /** 触发任务创建时间 */  
  69.     private Timestamp createTime;   
  70.     /** 最后一次触发时间 */  
  71.     private Timestamp lastTime;   
  72.        
  73.        
  74.     public String getId()   
  75.     {   
  76.         return id;   
  77.     }   
  78.     public void setId(String id)   
  79.     {   
  80.         this.id = id;   
  81.     }   
  82.     public String getTaskDesc()   
  83.     {   
  84.         return taskDesc;   
  85.     }   
  86.     public void setTaskDesc(String taskDesc)   
  87.     {   
  88.         this.taskDesc = taskDesc;   
  89.     }   
  90.     public int getState()   
  91.     {   
  92.         return state;   
  93.     }   
  94.     public void setState(int state)   
  95.     {   
  96.         this.state = state;   
  97.     }   
  98.     public String getClazz()   
  99.     {   
  100.         return clazz;   
  101.     }   
  102.     public void setClazz(String clazz)   
  103.     {   
  104.         this.clazz = clazz;   
  105.     }   
  106.     public String getInParam()   
  107.     {   
  108.         return inParam;   
  109.     }   
  110.     public void setInParam(String inParam)   
  111.     {   
  112.         this.inParam = inParam;   
  113.     }   
  114.     public String getCycle()   
  115.     {   
  116.         return cycle;   
  117.     }   
  118.     public void setCycle(String cycle)   
  119.     {   
  120.         this.cycle = cycle;   
  121.     }   
  122.     public String getCycleLimit()   
  123.     {   
  124.         return cycleLimit;   
  125.     }   
  126.     public void setCycleLimit(String cycleLimit)   
  127.     {   
  128.         this.cycleLimit = cycleLimit;   
  129.     }   
  130.     public String getDayLimit()   
  131.     {   
  132.         return dayLimit;   
  133.     }   
  134.     public void setDayLimit(String dayLimit)   
  135.     {   
  136.         this.dayLimit = dayLimit;   
  137.     }   
  138.     public String getHourLimit()   
  139.     {   
  140.         return hourLimit;   
  141.     }   
  142.     public void setHourLimit(String hourLimit)   
  143.     {   
  144.         this.hourLimit = hourLimit;   
  145.     }   
  146.     public Timestamp getCreateTime()   
  147.     {   
  148.         return createTime;   
  149.     }   
  150.     public void setCreateTime(Timestamp createTime)   
  151.     {   
  152.         this.createTime = createTime;   
  153.     }   
  154.     public Timestamp getLastTime()   
  155.     {   
  156.         return lastTime;   
  157.     }   
  158.     public void setLastTime(Timestamp lastTime)   
  159.     {   
  160.         this.lastTime = lastTime;   
  161.     }   
  162.        
  163.   
  164.   
  165. }  
package cn.com.xinli.netb.entitys;

import java.io.Serializable;
import java.sql.Timestamp;

/**
 *  触发任务表
 * @author diaoyf
 *
 */
public class Trigger implements Serializable
{
	public static final long serialVersionUID = 1;
	
	/** id */
	private String id;
	
	/** 触发任务描述 */
	private String taskDesc;
	
	/** 触发状态 0:允许触发 1:取消触发 */
	private int state;
	
	/**
	 * 回调对象的包、类路径名
	 * 触发管理器根据此包、类路径名,通过反射机制实例化对象
	 */
	private String clazz;
	/** 回调方法输入参数 */
	private String inParam;

	/**
	 * 触发周期
	 * <li>atonce 表示一次(由小时触发器管理)</li>
	 * <li>min 表示每分</li>
	 * <li>hour 表示每小时</li>
	 * <li>day 表示每天</li>
	 * <li>month 表示每月</li>
	 * <li>3month 表示每季度</li>
	 * <li>year 表示每年</li>
	 */
	private String cycle;
	
	/**
	 *  触发时间限制
	 *  格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间
	 *  格式"-", 表示无触发时间限制
	 *  
	 */
	private String cycleLimit; 
	/**
	 * 触发日期限制
	 * 如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";
	 * 如限制在每月10日,设置格式为"10-10";
	 * 如果没有日期限制,设置格式为"-"
	 * 如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日
	 */
	private String dayLimit; 
	/**
	 * 触发时间限制,时间规则最小"00:00",最大"23:59"
	 * 如邮件反馈限制在每天8~17时(8:00~17:59),hourLimit设置格式为"8:00-17:59";
	 * 如限制在12时(12:00~12:59),设置格式为"12:00-12:59".
	 * 如果没有时间限制,设置格式为"-"
	 * 如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59
	 */
	private String hourLimit;
	
	/** 触发任务创建时间 */
	private Timestamp createTime;
	/** 最后一次触发时间 */
	private Timestamp lastTime;
	
	
	public String getId()
	{
		return id;
	}
	public void setId(String id)
	{
		this.id = id;
	}
	public String getTaskDesc()
	{
		return taskDesc;
	}
	public void setTaskDesc(String taskDesc)
	{
		this.taskDesc = taskDesc;
	}
	public int getState()
	{
		return state;
	}
	public void setState(int state)
	{
		this.state = state;
	}
	public String getClazz()
	{
		return clazz;
	}
	public void setClazz(String clazz)
	{
		this.clazz = clazz;
	}
	public String getInParam()
	{
		return inParam;
	}
	public void setInParam(String inParam)
	{
		this.inParam = inParam;
	}
	public String getCycle()
	{
		return cycle;
	}
	public void setCycle(String cycle)
	{
		this.cycle = cycle;
	}
	public String getCycleLimit()
	{
		return cycleLimit;
	}
	public void setCycleLimit(String cycleLimit)
	{
		this.cycleLimit = cycleLimit;
	}
	public String getDayLimit()
	{
		return dayLimit;
	}
	public void setDayLimit(String dayLimit)
	{
		this.dayLimit = dayLimit;
	}
	public String getHourLimit()
	{
		return hourLimit;
	}
	public void setHourLimit(String hourLimit)
	{
		this.hourLimit = hourLimit;
	}
	public Timestamp getCreateTime()
	{
		return createTime;
	}
	public void setCreateTime(Timestamp createTime)
	{
		this.createTime = createTime;
	}
	public Timestamp getLastTime()
	{
		return lastTime;
	}
	public void setLastTime(Timestamp lastTime)
	{
		this.lastTime = lastTime;
	}
	


}

 

 

 

 

步骤2:建立 trigger ejb 的本地接口和远程接口,Bean实现

 

TriggerBean.java

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import java.rmi.RemoteException;   
  4. import java.util.Date;   
  5.   
  6. import javax.ejb.SessionBean;   
  7.   
  8. import org.apache.log4j.Logger;   
  9.   
  10. import cn.com.xinli.netb.ejb.trigger.TriggerTask;   
  11.   
  12. public class TriggerBean implements SessionBean   
  13. {   
  14.     static Logger log = Logger.getLogger(TriggerBean.class);   
  15.        
  16.     private javax.ejb.SessionContext m_ctx = null;   
  17.   
  18.     /**  
  19.      * Sets the session context. Required by EJB spec.  
  20.      *   
  21.      * @param ctx  
  22.      *            A SessionContext object.  
  23.      */  
  24.     public void setSessionContext(javax.ejb.SessionContext ctx)    
  25.     {   
  26.         m_ctx = ctx;   
  27.     }   
  28.   
  29.     /**  
  30.      * Creates a bean. Required by EJB spec.  
  31.      *   
  32.      * @exception throws  
  33.      *                CreateException.  
  34.      */  
  35.     public void ejbCreate() throws javax.ejb.EJBException,   
  36.             javax.ejb.CreateException    
  37.     {   
  38.     }   
  39.   
  40.     /**  
  41.      * Removes the bean. Required by EJB spec.  
  42.      */  
  43.     public void ejbRemove()    
  44.     {   
  45.     }   
  46.   
  47.     /**  
  48.      * Loads the state of the bean from secondary storage. Required by EJB spec.  
  49.      */  
  50.     public void ejbActivate()    
  51.     {   
  52.     }   
  53.   
  54.     /**  
  55.      * Serializes the state of the bean to secondary storage. Required by EJB  
  56.      * spec.  
  57.      */  
  58.     public void ejbPassivate()    
  59.     {   
  60.     }   
  61.        
  62.     // ------------------------------------------   
  63.     // 业务方法   
  64.     // ------------------------------------------   
  65.     public String runTask(String triggerId, String clazz, String inParam) throws RemoteException   
  66.     {   
  67.         TriggerTask task = null;   
  68.         try  
  69.         {   
  70.             task = (TriggerTask)Class.forName(clazz).newInstance();   
  71.         }   
  72.         catch (Exception e)   
  73.         {   
  74.             log.error("反射调用触发任务类异常", e);   
  75.             throw new RemoteException("反射调用触发任务类异常");   
  76.         }   
  77.            
  78.         log.info("调用触发实现类,类名:" + clazz + ",参数:" + inParam + ",调用时间:" + new Date());   
  79.            
  80.         //回调任务类,并得到运行结果   
  81.         return task.doTask(triggerId, inParam);   
  82.     }   
  83. }  
package cn.com.xinli.netb.ejb.trigger.service;

import java.rmi.RemoteException;
import java.util.Date;

import javax.ejb.SessionBean;

import org.apache.log4j.Logger;

import cn.com.xinli.netb.ejb.trigger.TriggerTask;

public class TriggerBean implements SessionBean
{
	static Logger log = Logger.getLogger(TriggerBean.class);
	
	private javax.ejb.SessionContext m_ctx = null;

	/**
	 * Sets the session context. Required by EJB spec.
	 * 
	 * @param ctx
	 *            A SessionContext object.
	 */
	public void setSessionContext(javax.ejb.SessionContext ctx) 
	{
		m_ctx = ctx;
	}

	/**
	 * Creates a bean. Required by EJB spec.
	 * 
	 * @exception throws
	 *                CreateException.
	 */
	public void ejbCreate() throws javax.ejb.EJBException,
			javax.ejb.CreateException 
	{
	}

	/**
	 * Removes the bean. Required by EJB spec.
	 */
	public void ejbRemove() 
	{
	}

	/**
	 * Loads the state of the bean from secondary storage. Required by EJB spec.
	 */
	public void ejbActivate() 
	{
	}

	/**
	 * Serializes the state of the bean to secondary storage. Required by EJB
	 * spec.
	 */
	public void ejbPassivate() 
	{
	}
	
	// ------------------------------------------
	// 业务方法
	// ------------------------------------------
	public String runTask(String triggerId, String clazz, String inParam) throws RemoteException
	{
		TriggerTask task = null;
		try
		{
			task = (TriggerTask)Class.forName(clazz).newInstance();
		}
		catch (Exception e)
		{
			log.error("反射调用触发任务类异常", e);
			throw new RemoteException("反射调用触发任务类异常");
		}
		
		log.info("调用触发实现类,类名:" + clazz + ",参数:" + inParam + ",调用时间:" + new Date());
		
		//回调任务类,并得到运行结果
		return task.doTask(triggerId, inParam);
	}
}

 

 TriggerHome.java

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import javax.ejb.EJBHome;   
  4.   
  5. public interface TriggerHome extends EJBHome   
  6. {   
  7.     TriggerRemote create() throws java.rmi.RemoteException, javax.ejb.CreateException;    
  8. }  
package cn.com.xinli.netb.ejb.trigger.service;

import javax.ejb.EJBHome;

public interface TriggerHome extends EJBHome
{
	TriggerRemote create() throws java.rmi.RemoteException, javax.ejb.CreateException; 
}

 

TriggerRemote.java 

 

Java代码 复制代码
  1. package cn.com.xinli.netb.ejb.trigger.service;   
  2.   
  3. import java.rmi.RemoteException;   
  4.   
  5. import javax.ejb.EJBObject;   
  6.   
  7. public interface TriggerRemote extends EJBObject   
  8. {   
  9.     /**  
  10.      * 调用反馈任务  
  11.      * @param triggerId 任务ID  
  12.      * @param clazz 反射类名  
  13.      * @param inParam 运行参数  
  14.      * @return  
  15.      *  <li>00: 成功,触发管理器将从触发表中取消此任务</li>  
  16.      *  <li>01: 失败,并触发管理器将从触发表中取消此任务</li>  
  17.      *  <li>10: 成功,触发管理器在触发表中保持此任务</li>  
  18.      *  <li>11: 失败,触发管理器在触发表中保持此任务</li>  
  19.      * @throws RemoteException  
  20.      */  
  21.     public String runTask(String triggerId, String clazz, String inParam) throws RemoteException;   
  22. }  
package cn.com.xinli.netb.ejb.trigger.service;

import java.rmi.RemoteException;

import javax.ejb.EJBObject;

public interface TriggerRemote extends EJBObject
{
	/**
	 * 调用反馈任务
	 * @param triggerId 任务ID
	 * @param clazz 反射类名
	 * @param inParam 运行参数
	 * @return
	 * 	<li>00: 成功,触发管理器将从触发表中取消此任务</li>
	 * 	<li>01: 失败,并触发管理器将从触发表中取消此任务</li>
	 * 	<li>10: 成功,触发管理器在触发表中保持此任务</li>
	 * 	<li>11: 失败,触发管理器在触发表中保持此任务</li>
	 * @throws RemoteException
	 */
	public String runTask(String triggerId, String clazz, String inParam) throws RemoteException;
}

 

 

步骤3:建立 TriggerManage ,用来操作 自动任务

Java代码
package cn.com.xinli.netb.ejb.trigger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Timestamp;

import org.apache.log4j.Logger;
import org.hibernate.Session;

import cn.com.xinli.netb.ejb.common.HibernateUtil;
import cn.com.xinli.netb.entitys.Trigger;

/**
 * 触发任务管理
 * @author diaoyf
 *
 */
public class TriggerManage
{
	private static Logger log = Logger.getLogger(TriggerManage.class);
	

	
	/**
	 * 增加触发任务
	 * @param taskDesc 任务描述
	 * @param clazz 
	 * 		回调对象的包、类路径名。
	 * 		触发管理器根据此包、类路径名,通过反射机制实例化对象
	 * @param inParam
	 * 		回调方法输入参数
	 * @param cycle
	 * 		触发周期
	 * 	<li>atonce 表示一次(由小时触发器管理)</li>
	 * 	<li>min 表示每分</li>
	 * 	<li>hour 表示每小时</li>
	 * 	<li>day 表示每天</li>
	 * 	<li>week 表示每周</li>
	 * 	<li>month 表示每月</li>
	 * 	<li>3month 表示每季度</li>
	 * 	<li>year 表示每年</li>
	 * @param cycleLimit
	 * 		触发时间限制。
	 *  	<li>格式"2007/10/2 8:15:28-2007/10/3 18:15:30",表示任务存在时间;</li>
	 *  	<li>格式"-", 表示无触发时间限制。</li>
	 * @param dayLimit
	 * 		触发日期限制。
	 * 		<li>如月账单反馈限制在每月10~15日(包括15日),dayLimit设置格式为"10-15";</li>
	 * 		<li>如限制在每月10日,设置格式为"10-10";</li>
	 * 		<li>如果没有日期限制,设置格式为"-";</li>
	 * 		<li>如果起始日期大于终止日期,如"25-10",表示当月25日到下月10日。</li>
	 * 		<li>周触发任务: "w-1"表示周日发送、"w-2"表示周1发送、..."w-7"表示周6发送</li>
	 * @param hourLimit
	 * 		触发时间限制,时间规则最小"00:00",最大"23:59"。</li>
	 * 		<li>如邮件反馈限制在每天8~17时(8:00-17:59),hourLimit设置格式为"8:00-17:59";</li>
	 * 		<li>如限制在12时(12:00-12:59),设置格式为"12:00-12:59";</li>
	 * 		<li>如果没有时间限制,设置格式为"-";</li>
	 * 		<li>如果起始日期大于终止日期,如"23:00-8:59",表示当日23:00到下一日8:59。</li>
	 * @return 触发ID
	 * @throws Exception
	 */
	public static String addTask(
			String taskDesc,
			String clazz,
			String inParam,
			String cycle,
			String cycleLimit,
			String dayLimit,
			String hourLimit) throws Exception
	{
		Trigger trigger = new Trigger();
		trigger.setTaskDesc(taskDesc);
		trigger.setState(0);
		trigger.setClazz(clazz);
		trigger.setInParam(inParam);
		trigger.setCycle(cycle);
		trigger.setCycleLimit(cycleLimit);
		trigger.setHourLimit(hourLimit);
		trigger.setDayLimit(dayLimit);
		trigger.setCreateTime(new Timestamp(System.currentTimeMillis()));
		trigger.setLastTime(new Timestamp(0)); //默认1970年
		
		return addTask(trigger);
	}
	
	
	
	

	/**
	 * 增加触发任务
	 * @param trigger
	 * @throws Exception
	 */
	static String addTask(Trigger trigger) throws Exception
	{
		Session session = null;
		try 
		{
			session = HibernateUtil.getSession();
			
			//事物
//			Transaction tran = session.beginTransaction();

			session.save(trigger);
			session.flush();
			
//			tran.commit();
			
			return trigger.getId();
		} 
		catch (Exception e) 
		{
			log.error("获取Session异常", e);
			e.printStackTrace();
			throw new Exception("获取Session异常");
		} 
		finally
		{
			HibernateUtil.closeSession(session);
		}


	}
	

	
	/**
	 *  置触发任务为1(取消)
	 * @param trigger
	 */
	static void cancelTask(Trigger trigger)throws Exception
	{
		
		Session session = null;
		try
		{
			session = HibernateUtil.getSession();
			
			//修改状态标志, 1:取消
			trigger.setState(1);
			
			//事物
//			Transaction tran = session.beginTransaction();

			session.update(trigger);
			
//			tran.commit();
		}
		catch (Exception e)
		{
			log.error("置触发任务为1(取消)失败", e);
			throw new Exception("置触发任务为1(取消)失败");
		}
		finally
		{
			HibernateUtil.closeSession(session);
		}

	}
	
	/**
	 *  置触发任务为1(取消)
	 * @param trigger
	 */
	public static void cancelTask(String triggerId) throws Exception
	{
//		Session session = null;
		Connection conn = null;
		PreparedStatement prepStmt = null;
		try 
		{
//			session = HibernateUtil.currentSession();
			conn = HibernateUtil.getConnection();
			
//			conn.setAutoCommit(false);
			
			String sql = "UPDATE NETB_TRIGGER SET state = ? WHERE id = ?";
			prepStmt = conn.prepareStatement(sql);
			prepStmt.setInt(1, 1);
			prepStmt.setString(2, triggerId);
			
			prepStmt.execute();
			
//			conn.commit();
		} 
		catch (Exception e) 
		{
//			conn.rollback();
			log.error("置任务状态为1(取消)时,数据库操作异常", e);
			throw new Exception("置任务状态为1(取消)时,数据库操作异常");
		} 
		finally 
		{
			try
			{
				conn.close();
			}
			catch (Exception e)
			{
				
			}
		}
	}
	
	public static void updateTask(  String triggerId,
									String taskDesc,
									String clazz,
									String inParam,
									String cycle,
									String cycleLimit,
									String dayLimit,
									String hourLimit) throws Exception
	{
		Connection conn = null;
		PreparedStatement prepStmt = null;
		try 
		{
//			session = HibernateUtil.currentSession();
			conn = HibernateUtil.getConnection();
			
//			conn.setAutoCommit(false);
			
			String sql = "UPDATE NETB_TRIGGER SET taskDesc = ? ,clazz=?,inParam=?," +
					                            "cycle=?,cycleLimit=?,dayLimit=? and hourLimit=?"+
			                                    "WHERE id = ?";
			prepStmt = conn.prepareStatement(sql);
			prepStmt.setString(1, taskDesc);
			prepStmt.setString(2, clazz);
			prepStmt.setString(3, inParam);
			prepStmt.setString(4, cycle);
			prepStmt.setString(5, cycleLimit);
			prepStmt.setString(6, dayLimit);
			prepStmt.setString(7, hourLimit);
			prepStmt.setString(8, triggerId);
			prepStmt.execute();
			
//			conn.commit();
		} 
		catch (Exception e) 
		{
//			conn.rollback();
			log.error("置任务状态为1(取消)时,数据库操作异常", e);
			throw new Exception("置任务状态为1(取消)时,数据库操作异常");
		} 
		finally 
		{
			try
			{
				conn.close();
			}
			catch (Exception e)
			{
				
			}
		}
	}
	public static void main(String[] args) throws Exception
	{
		TriggerManage tm=new TriggerManage();
		Trigger trigger=new Trigger();
		trigger.setTaskDesc("测试2");
		System.out.println(tm.addTask(trigger));;
		
	}
}
 

步骤4:在ejb层建立 测试的业务方法,供自动任务调用

package cn.com.xinli.netb.ejb.trigger;
import org.apache.log4j.Logger;
import cn.com.xinli.netb.ejb.trigger.TriggerTask;

/**
 * 自动任务测试任务
 * 
 * @author huxl
 * 2008/9/23
 */
public class TriggerTaskTest implements TriggerTask 
{

    static Logger log = Logger.getLogger(TriggerTaskTest.class);
    public  String doTask(String triggerId, String inParam) 
    {
    	
    	log.info("自动任务测试任务开始执行");
    	log.info("triggerId:"+triggerId);
    	log.info("inParam:"+inParam);
    	return "10"; //成功继续保持此业务
    }
}
	

  

 

步骤5:自动任务框架,主要有两个线程,分钟线程 和小时线程 不停的去扫描数据库找到满足触发条件的任务,利用发射机制去执行,代码见附件。
如何使用这个自动任务框架
 
     1.讲ejb TriggerEJB 项目打成jar包放在jboss下
2.配置 TriggerThread 项目的 数据库配置文件
3.手工插入一条任务
 
 
4.启动 TriggerThread  中的Main ,观察我们插入的分钟任务的执行,看日志
TriggerThread 框架的日志:
0    [main] INFO  Main(34) - DB_URL:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
0    [main] INFO  Main(35) - DB_USER:root
16   [main] INFO  Main(36) - DB_PASSWD:12345678
16   [main] INFO  Main(37) - EJB_URL:jnp://127.0.0.1:1099
16   [Thread-0] INFO  TriggerHourThread(22) - 小时任务线程运行....
16   [Thread-1] INFO  TriggerMinThread(20) - 分钟任务线程运行....
609  [Thread-1] INFO  TriggerMinThread(38) - 运行触发任务
703  [Thread-1] INFO  TriggerMinThread(77) - sql:SELECT * FROM NETB_TRIGGER  WHERE 	state = ? AND 	cycle = ?  ORDER BY  	createTime
719  [Thread-1] INFO  TriggerMinThread(99) - 准备处理分钟任务:id=2003
719  [Thread-1] INFO  TriggerMinThread(130) - 开始处理分钟任务
719  [Thread-1] INFO  TriggerMinThread(149) - 上次触发时间:2009-08-01 18:00:32.0
750  [Thread-1] INFO  TriggerMinThread(150) - 当前时间:2009-08-01 18:15:04
750  [Thread-1] INFO  TriggerMinThread(157) - 分钟任务,id=2003距离上次触发已超过1分钟
781  [Thread-1] INFO  EJBHomeFactory(72) - EJB Home缓存中没有TriggerHome,创建之。
1094 [Thread-1] INFO  EJBHomeFactory(76) - 在JNDI中查询到了“Trigger”
1094 [Thread-1] INFO  EJBHomeFactory(79) - 成功获得远程Home对象,并存入缓存
1094 [Thread-1] INFO  Ejb(51) - 从Home工厂获取到了“TriggerHome”
1187 [Thread-1] INFO  Ejb(55) - 通过home成功获得remote对象
1203 [Thread-1] INFO  TriggerMinThread(162) - 分钟任务,id=2003返回值:10
 
jboss的日志
s_4_0_4_GA date=200605151000)] Started in 21s:578ms
18:15:05,062 INFO  [TriggerBean] 调用触发实现类,类名:cn.com.xinli.netb.ejb.trig
ger.TriggerTaskTest,参数:00,调用时间:Sat Aug 01 18:15:05 CST 2009
18:15:05,062 INFO  [TriggerTaskTest] 自动任务测试任务开始执行
18:15:05,062 INFO  [TriggerTaskTest] triggerId:2003
18:15:05,062 INFO  [TriggerTaskTest] inParam:00
 
OK!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 首先,感谢您的提问。关于手写一个 Spring 框架,这是一个非常复杂的任务,需要深入了解 Spring 框架的原理和设计思想。如果您想要手写一个 Spring 框架,建议您先学习 Spring 框架的基本原理和核心组件,例如 IoC 容器、AOP、MVC 等。然后,您可以根据自己的需求和业务场景,逐步实现自己的 Spring 框架。当然,这需要您具备较强的 Java 编程能力和系统设计能力。希望我的回答能够帮助到您。 ### 回答2: 手写一个Spring框架是一项复杂且庞大的任务,需要深入理解Spring框架的核心概念和原理。以下是一个简要的步骤指南: 1. 了解Spring框架的核心概念和原理,包括依赖注入、面向切面编程、控制反转等。 2. 创建一个独立的IoC容器,用于管理对象的创建和依赖注入。可以通过反射机制实现对象的自动注入,同时考虑循环依赖的情况。 3. 实现一个简单的AOP框架,通过动态代理机制实现方法拦截和增强。可以使用JDK自带的动态代理或者CGLIB库等。 4. 设计和实现一个MVC框架,用于处理Web请求和返回结果。可以使用Servlet作为底层技术,设计并实现自己的DispatcherServlet。 5. 创建一个配置文件解析器,用于解析Spring配置文件中的Bean定义和依赖关系。可以使用DOM、SAX、XML解析器等。 6. 编写一个Bean工厂,负责管理Bean的生命周期和依赖关系。可以在Bean创建时对其进行初始化和销毁的处理。 7. 实现一个简单的事务管理器,用于处理数据库事务。可以使用JDBC或者类似的持久化框架。 手写一个Spring框架需要深入理解Java反射、动态代理、设计模式等知识,并具备一定的编程和架构能力。以上只是一个简要的步骤指南,实际的开发过程中还需要考虑到更多的细节和边界情况。因此,对于初学者来说,手写一个完整的Spring框架可能是一个挑战,建议先熟悉和使用官方提供的Spring框架,通过实践逐步深入理解其原理和内部实现,再考虑手写一个简化的版本。 ### 回答3: 手写一个Spring框架是一项庞大而复杂的任务,需要深入理解Spring的设计原理和内部机制。以下是手写一个简化版Spring框架的高级步骤: 第一步:实现IoC容器 IoC(控制反转)是Spring框架的核心概念,通过实现一个简单的IoC容器,来管理对象的创建和依赖注入。容器可以采用单例模式,在初始化时读取配置文件,通过反射实例化并注入依赖。容器会根据配置文件中的Bean定义,创建并管理对象之间的依赖关系。 第二步:实现依赖注入 依赖注入是Spring框架的另一个重要概念,通过实现依赖注入功能,实现对象之间的解耦。可以通过反射遍历对象的属性,扫描注解或配置文件,将依赖的对象自动注入到属性中。 第三步:实现AOP功能 AOP(面向切面编程)是Spring框架中提供的另一个重要功能,通过实现AOP功能,能够在不修改原有代码的情况下,对业务逻辑进行增强。可以使用动态代理等机制,在目标方法的前后增加额外的操作。 第四步:实现Web MVC功能 Spring框架还提供了强大的Web MVC功能,通过实现简化版的请求处理、路由和视图解析等功能,来实现一个基本的Web应用。可以通过Servlet或者自定义HttpHandler来处理请求,并使用模板引擎等技术进行视图解析和渲染。 第五步:实现其他特性 除了上述核心功能外,Spring框架还提供了诸如事务管理、数据访问、安全等一系列扩展功能。可以根据实际需要,逐步实现这些特性。 最后,为了保持代码的可维护性和可扩展性,建议使用设计模式、模块化的方式来实现框架的各个功能。此外,持续学习和了解Spring框架的最新发展和技术变化,可以帮助优化和提升手写框架的质量和性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值