zoukankan      html  css  js  c++  java
  • Quartz与Spring整合进行热部署的实现(二)

    Spring的org.springframework.scheduling.quartz.JobDetailBean提供Job可序列化的实现(具体实现可查看源码)

    此时.我们原来的job就可以继承QuartzJobBean,便会自动序列化到数据库,quartz的具体配置文件如下

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"
        default-lazy-init="true">
    
        <description>quartz配置</description>
        
        <!-- quartz使用的数据源配置 -->
        <bean id="quartzDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="${quartz.jdbc.driver}" />
            <property name="url" value="${quartz.jdbc.url}" />
            <property name="username" value="${quartz.jdbc.username}" />
            <property name="password" value="${quartz.jdbc.password}" />
        </bean>
        
        <!-- 另一个事务管理器, Jdbc单数据源事务 -->
        <bean id="quartzTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="quartzDataSource" />
        </bean>
        
        <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
            <property name="dataSource" ref="quartzDataSource"/>
            <property name="applicationContextSchedulerContextKey" value="applicationContext"/>
            <property name="configLocation" value="classpath:quartz.properties"/><!--
            这个是必须的,QuartzScheduler 延时启动,应用启动完后 QuartzScheduler 再启动 
            -->
            <property name="startupDelay" value="30"/><!--
            这个是可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
            -->
            <property name="overwriteExistingJobs" value="true"/>
            <property name="jobDetails" >
                <list>
                    <ref bean="serverHealthJobDetail"/>
                </list>    
            </property>            
        </bean>
        
        <!-- 运行次数记录 -->
        <bean id="serverHealthJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
            <!--requestsRecovery属性为true,则当Quartz服务被中止后,再次启动任务时会尝试恢复执行之前未完成的所有任务-->
            <property name="requestsRecovery" value="true"/>
            <!-- 标识job是持久的,删除触发器的时候不被删除 -->
            <property name="durability" value="true"/>
            <property name="jobClass" value="cn.yzzn.hvac.quartz.job.ServerHealthJob"/>
        </bean>
        
    </beans>

    我们看到<property name="applicationContextSchedulerContextKey" value="applicationContext"/>此标签

    Spring会帮我们自动注入applicationContext.并非上一篇文章中,通过Spring的工具手动获取applicationContext.

    ServerHealthJob代码如下

    public abstract class JobSupport extends QuartzJobBean {
     
        private BuildingManager buildingManager;
        private PlcManager plcManager;
     
        private static Logger logger = LoggerFactory.getLogger(JobSupport.class);
     
        private ApplicationContext applicationContext;
        /**
         * 从SchedulerFactoryBean注入的applicationContext.
         */
        public void setApplicationContext(ApplicationContext applicationContext) {
            this.applicationContext = applicationContext;
        }
     
        public <T> T getBean(String beanName, Class<T> clazz) {
            return this.applicationContext.getBean(beanName, clazz);
        }
         
        @Override
        protected void executeInternal(JobExecutionContext context)
                throws JobExecutionException {
            if (ObjectUtils.isNullOrEmptyString(buildingManager)) {
                buildingManager = getBean("buildingManager", BuildingManager.class);
            }
            if (ObjectUtils.isNullOrEmptyString(plcManager)) {
                plcManager = getBean("plcManager", PlcManager.class);
            }
     
            List<Building> buildingList = buildingManager.getBuildings();
     
            int size = buildingList.size();
            for (int i = 0; i < size; i++) {
                Building building = buildingList.get(i);
                 
                Set<Plc> plcSet = building.getPlcs();
                for (Plc plc : plcSet) {
                    innerIter(building, plc, i, size);
                }
            }
        }
     
        public abstract void innerIter(Building building, Plc plc,
                int index, int size);
     
    }
    public class ServerHealthJob extends JobSupport {
     
        @Override
        public void innerIter(Building building, Plc plc, int index, int size) {
            // TODO Auto-generated method stub
             
        }
         
    }

    ServerHealthJob就可以被Spring轻松的序列化到数据库.解决了上篇博文中繁琐的操作.

    JobSupport是本人系统业务需求,同学们可自定义实现只要继承QuartzJobBean即刻.

    数据库中已存在次jobDetail

    TriggerManager也没多大变化

    /**
     * Quartz Scheduler 管理类
     * 不带groupName参数的方法都采用自动填充默认组的形式 Scheduler.DEFAULT_GROUP
     * @author PigWing
     *
     */
    public class SchedulerManagerImpl implements SchedulerManager {
     
        private QuartzDao quartzDao;
        private Scheduler scheduler;
         
        private static Logger logger = LoggerFactory.getLogger(UserController.class);
         
     
        /***
         * 增加一个触发器任务,采用默认组形式
         */
        public void addTrigger(String triggerName, String jobName,
                String cronExpression) throws SchedulerException, ParseException {
            addTrigger(triggerName, Scheduler.DEFAULT_GROUP, jobName, Scheduler.DEFAULT_GROUP, cronExpression);
        }
     
        /**
         * 
         * 增加一个触发器任务
         */
        public void addTrigger(String triggerName, String triggerGroupName,
                String jobName, String jobGrourpName, String cronExpression) throws SchedulerException, ParseException {
            if(StringUtils.isEmpty(triggerName)) {
                throw new RuntimeException("triggerName can not be null");
            }
             
            try {
                JobDetail jobDetail = scheduler.getJobDetail(jobName, jobGrourpName);
                if(jobDetail != null) {
                    scheduler.addJob(jobDetail, true);
                    CronTrigger cronTrigger = new CronTrigger(triggerName, triggerGroupName, jobDetail.getName(), jobGrourpName);
                    cronTrigger.setCronExpression(cronExpression);
                    scheduler.scheduleJob(cronTrigger);
                    scheduler.rescheduleJob(cronTrigger.getName(), cronTrigger.getGroup(), cronTrigger);
                }else {
                    logger.error("cant not find jobDetail: " + jobGrourpName);
                }
            }catch(SchedulerException e) {
                logger.error(e.getMessage());
                throw e;
            }
        }
     
     
        /**
         * 返回所有触发器信息
         */
        public List<Map<String, Object>> getAllTriggers() {
            return quartzDao.getQuartzTriggers();
        }
     
        /**
         * 停止触发器
         */
        public void parseTrigger(String triggerName, String groupName)
                throws SchedulerException {
            try {
                scheduler.pauseTrigger(triggerName, groupName);
            }catch(SchedulerException e) {
                logger.error(e.getMessage());
                throw e;
            }
             
        }
     
        /**
         * 停止触发器,采用默认组形式
         */
        public void parseTrigger(String triggerName) throws SchedulerException {
            parseTrigger(triggerName, Scheduler.DEFAULT_GROUP);
     
        }
     
        /**
         * 重启触发器
         */
        public void resumeTrigger(String triggerName, String groupName)
                throws SchedulerException {
            try {
                scheduler.resumeTrigger(triggerName, groupName);
            }catch(SchedulerException e) {
                logger.error(e.getMessage());
                throw e;
            }
             
     
        }
     
        /**
         * 重启触发器,采用默认组形式
         */
        public void resumeTrigger(String triggerName) throws SchedulerException {
            resumeTrigger(triggerName, Scheduler.DEFAULT_GROUP);
        }
     
        /**
         * 移除触发器
         */
        public boolean removeTrigger(String triggerName, String groupName)
                throws SchedulerException {
            try {
                parseTrigger(triggerName, groupName);
                return scheduler.unscheduleJob(triggerName, groupName);
            }catch(SchedulerException e) {
                logger.error(e.getMessage());
                throw e;
            }
        }
     
        /**
         * 移除触发器,采用默认组形式
         */
        public boolean removeTrigger(String triggerName) throws SchedulerException {
            try {
                return removeTrigger(triggerName, Scheduler.DEFAULT_GROUP);
            }catch(SchedulerException e) {
                logger.error(e.getMessage());
                throw e;
            }
        }
     
        /**
         * 返回所有的任务名称
         */
        public String[] getJobNames(String groupName) throws SchedulerException {
            return scheduler.getJobNames(groupName);
        }
     
        public String[] getJobNames() throws SchedulerException {
            return scheduler.getJobNames(Scheduler.DEFAULT_GROUP);
        }
     
        @Autowired
        public void setQuartzDao(QuartzDao quartzDao) {
            this.quartzDao = quartzDao;
        }
     
        @Autowired
        public void setScheduler(Scheduler scheduler) {
            this.scheduler = scheduler;
        }
     
         
    }

    本文转自:http://www.cnblogs.com/pigwing/archive/2011/07/12/2104002.html

  • 相关阅读:
    反射遍历实体类
    Socket通讯实例-基本Socket
    c#向数据库插入较大数据(SqlBulkCopy)
    C#中(int)、int.Parse()、int.TryParse()和Convert.ToInt32()的区别
    jquery实现限制textarea输入字数
    jquery回车执行某个事件
    asp.net自定义404页面
    iis上json解析失败404
    echart 扩展地图不显示问题
    bootstarp 样式细节(tooltip布局)
  • 原文地址:https://www.cnblogs.com/dreammyle/p/4122086.html
Copyright © 2011-2022 走看看