原文地址:https://blog.csdn.net/ljqwstc/article/details/78257091

首先添加maven的依赖:

<!--quartz定时任务-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>

spring配置文件中添加如下bean

<!--
自动装配类
@Autowired
private Scheduler scheduler;
-->
<!-- quartz持久化存储 -->
<!--实现动态配置只需定义一下schedulerbean就可以了-->
<bean name="schedulerFactoryBean"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="true">
<property name="dataSource">
<ref bean="dataSource"/>
</property>
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="quartzProperties">
<props>
<prop key="org.quartz.scheduler.instanceId">AUTO</prop>
<!-- 线程池配置 -->
<prop key="org.quartz.threadPool.class">${org.quartz.threadPool.class}</prop>
<prop key="org.quartz.threadPool.threadCount">${org.quartz.threadPool.threadCount}</prop>
<prop key="org.quartz.threadPool.threadPriority">${org.quartz.threadPool.threadPriority}</prop>
<prop key="org.quartz.jobStore.misfireThreshold">${org.quartz.jobStore.misfireThreshold}</prop>
<!-- JobStore 配置 -->
<prop key="org.quartz.jobStore.class">${org.quartz.jobStore.class}</prop>
<!-- 集群配置 -->
<prop key="org.quartz.jobStore.isClustered">true</prop>
<prop key="org.quartz.jobStore.clusterCheckinInterval">15000</prop>
<prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">1</prop>
<!-- 数据表设置 -->
<prop key="org.quartz.jobStore.tablePrefix">${org.quartz.jobStore.tablePrefix}</prop>
<prop key="org.quartz.jobStore.dataSource">${org.quartz.jobStore.dataSource}</prop>
</props>
</property>
</bean>
解释:
1.一般公司项目中都已经定义好了dataSource,比如我们公司是用DruidDataSource,所以直接拿来用就可以了。如果没有的话,需要配置一个dataSource,这里就不阐述了。
2.因为是要持久化的,所以org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX  
这样设置以后就是持久化,会将任务的一些相关信息和配置存入到数据库中。具体需要用到什么数据表,下面会有。
3.Scheduler简单说相当于一个容器一样,里面放着jobDetail和Trriger
4.其他的一些配置可以根据自己的业务需求,到quartz的官网查看配置文档进行添加。

这个是quartz.properties文件

#============================================================================
# Configure Datasources
#============================================================================
#JDBC驱动
#org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver
#org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz?characterEncoding=utf-8
#org.quartz.dataSource.myDS.user = root
#org.quartz.dataSource.myDS.password = root
#org.quartz.dataSource.myDS.maxConnections =5
#集群配置
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 10
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true org.quartz.jobStore.misfireThreshold: 60000 #============================================================================
# Configure JobStore
#============================================================================ #默认配置,数据保存到内存
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true #数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:myDS

这个是quartz官方的表,运行就可以了,就建表成功了。

#
# Quartz seems to work best with the driver mm.mysql-2.0.7-bin.jar
#
# PLEASE consider using mysql with innodb tables to avoid locking issues
#
# In your Quartz properties file, you'll need to set
# org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
# DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS; CREATE TABLE QRTZ_JOB_DETAILS
(
SCHED_NAME VARCHAR(120) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_NONCONCURRENT VARCHAR(1) NOT NULL,
IS_UPDATE_DATA VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(13) NULL,
PREV_FIRE_TIME BIGINT(13) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(13) NOT NULL,
END_TIME BIGINT(13) NULL,
CALENDAR_NAME VARCHAR(200) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SIMPLE_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_CRON_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
CRON_EXPRESSION VARCHAR(200) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SIMPROP_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
STR_PROP_1 VARCHAR(512) NULL,
STR_PROP_2 VARCHAR(512) NULL,
STR_PROP_3 VARCHAR(512) NULL,
INT_PROP_1 INT NULL,
INT_PROP_2 INT NULL,
LONG_PROP_1 BIGINT NULL,
LONG_PROP_2 BIGINT NULL,
DEC_PROP_1 NUMERIC(13,4) NULL,
DEC_PROP_2 NUMERIC(13,4) NULL,
BOOL_PROP_1 VARCHAR(1) NULL,
BOOL_PROP_2 VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_BLOB_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_CALENDARS
(
SCHED_NAME VARCHAR(120) NOT NULL,
CALENDAR_NAME VARCHAR(200) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS
(
SCHED_NAME VARCHAR(120) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_FIRED_TRIGGERS
(
SCHED_NAME VARCHAR(120) NOT NULL,
ENTRY_ID VARCHAR(95) NOT NULL,
TRIGGER_NAME VARCHAR(200) NOT NULL,
TRIGGER_GROUP VARCHAR(200) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
FIRED_TIME BIGINT(13) NOT NULL,
SCHED_TIME BIGINT(13) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(200) NULL,
JOB_GROUP VARCHAR(200) NULL,
IS_NONCONCURRENT VARCHAR(1) NULL,
REQUESTS_RECOVERY VARCHAR(1) NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_SCHEDULER_STATE
(
SCHED_NAME VARCHAR(120) NOT NULL,
INSTANCE_NAME VARCHAR(200) NOT NULL,
LAST_CHECKIN_TIME BIGINT(13) NOT NULL,
CHECKIN_INTERVAL BIGINT(13) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE QRTZ_LOCKS
(
SCHED_NAME VARCHAR(120) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME)
)ENGINE=MyISAM DEFAULT CHARSET=utf8; commit;

ok,到这里,我们需要的配置基本完成,接下来,就是怎么样去创建任务,实现任务的动态添加,修改。

 
首先,我们回顾一下,如果要执行一个任务,是不是要自定义一个类,比如SendEmailJob,然后这个类实现Job接口,再重写excute方法?然后再定义jobDetail,Trigger,然后再Scheduler.schdulerJob(jobDetail,trigger),安排任务?
 
那如果业务需求改了,现在需要通知用户的任务,抓取新闻的任务,这样的话就需要写非常非常多的job实现类,对吧?
 
所以,考虑到这一点,我们可以写一个QuartzJobFactory类实现Job接口,作为统一的Job入口,并且在job的上下文中加入一个我们POJO类(保存着一些job的相关信息),那么,在QuartzJobFactory类的excute方法中,我们可以根据我们传进去的POJO类对象获取当前job的相关信息,从而实现动态的去具体执行什么任务(方法)。
 

下面详细解释下实现方法:

这个是我自己定义的POJO类对象,用于保存当前任务的详细信息。
 
public class ScheduleJob implements Serializable {

    private static final long serialVersionUID = -5115028108119830917L;
/**
* 任务名称
*/
private String jobName;
/**
* 任务分组
*/
private String jobGroup;
/**
* 触发器名称(默认和任务名称相同)
*/
private String triggerName;
/**
* 触发器分组(默认和任务分组相同)
*/
private String triggerGroup;
/**
* 任务需要调用的是哪个类的类名
*/
private String className;
/**
* 任务需要调用的是哪个类的方法名
*/
private String methodName;
/**
* 方法所需参数数组
*/
private ArrayList paramArray;
/**
* 任务运行时间表达式
*/
private String cron;
/**
* 任务运行时间(特指只运行一次的任务)
*/
private String runDate;
/**
* 任务描述
*/
private String desc;
getter and setter.....
}
这个POJO类主要的作用的,保存任务的一些相关信息。当我们在创建jobDetail的时候,可以获取他的dataMap,set进去。这样我们可以在QuartzJobFactory的excute方法中的参数中获取到dataMap,并从中拿到这个POJO类对象,从而获取了该job具体要怎么执行,执行哪个方法,方法参数是什么,就都有了!
 
接下来,我们继续看:
 
这个是我定义的QuartzJobFactory,Job的统一入口:
 
@PersistJobDataAfterExecution
public class QuartzJobFactory implements Job { /**
* The constant logger.
*/
private static final Logger logger = LoggerFactory.getLogger(Constants.LOG_SYSTEM_RUN); public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
ScheduleJob scheduleJob = (ScheduleJob) jobExecutionContext.getMergedJobDataMap().get("scheduleJob");
//获取service层接口名和接口方法名
String springBeanName = scheduleJob.getClassName();
String methodName = scheduleJob.getMethodName();
//获取参数数组和参数类型数组
ArrayList paramArray = scheduleJob.getParamArray();
Class[] paramType = new Class[paramArray.size()];
for (int i = 0; i < paramArray.size(); i++) {
paramType[i] = paramArray.get(i).getClass();
}
/**
* 反射运行service层的方法
*/
Object bean = SpringContextsUtil.getBean(springBeanName);
Method method = ReflectionUtils.findMethod(bean.getClass(), methodName, paramType);
ReflectionUtils.invokeMethod(method, bean, paramArray.toArray()); logger.info("任务名称 = [" + scheduleJob.getJobName() + "]," +
"任务调用的类=[" + scheduleJob.getClassName() + "]," +
"任务调用的方法=[" + scheduleJob.getMethodName() + "]---->>成功启动运行");
}
}
有状态的两个注解
支持并发
@PersistJobDataAfterExecution
如果不支持并发
@disallowconcurrentexecution
 
通过SpringContextsUtil工具类调用getBean去获取bean,这里的参数是String 类型的beanName,也就是我们配置文件配置bean是name那个属性。或者是我们在写Service层的时候,通过注@Service("beanName")   ,当然是推荐后者啦!简单方便。
获得了bean以后,在通过方法名获取Method,再利用反射就可以实现对Service层方法的调用了。
 
下面是我的SpringContextUtil工具类:
 
@Component
public class SpringContextsUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; public static Object getBean(String beanName) throws BeansException {
return applicationContext.getBean(beanName);
} public static <T> T getBean(String beanName, Class<T> clazs) {
return applicationContext.getBean(beanName, clazs);
} @Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextsUtil.applicationContext = applicationContext;
}
}
ok,现在就只剩下对任务的添加,删除,启动,暂停等动态操作了。
 
为了方便管理,在我的quartz项目中,我的jobName和triggerName相同,jobGroup和triggerGroup相同。
 
既然是对任务的一些动态操作。我创了一个QuartzProducer接口,里面有对job的动态操作的一些方法。如下:
public interface QuartzProducer {

    /**
* 添加简单任务,只运行一次的任务
*
* @param jobName
* @param jobGroup
* @param className
* @param methodName
* @param paramArray
* @param runDateTime 格式:yyyyMMddHHmmss
* @throws SchedulerException
* @throws ParseException
*/
public void addSimpleJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String runDateTime) throws SchedulerException, ParseException; /**
* 添加循环任务,特定时间循环运行,例如每个星期3,12点运行等
*
* @param jobName
* @param jobGroup
* @param className
* @param methodName
* @param paramArray
* @param cron
* @throws SchedulerException
*/
public void addCronJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String cron) throws SchedulerException; /**
* 修改简单任务,一般指修改运行时间
*
* @param jobName
* @param jobGroup
* @param runDateTime 格式:yyyyMMddHHmmss
*/
public void updateSimpleJob(String jobName, String jobGroup, String runDateTime) throws SchedulerException, ParseException; /**
* 修改cron任务,一般指修改循环运行时间
*
* @param jobName
* @param jobGroup
* @param cron
*/
public void updateCronJob(String jobName, String jobGroup, String cron) throws SchedulerException; /**
* 移除任务
*
* @param jobName
* @param jobGroup
*/
public void deleteJob(String jobName, String jobGroup) throws SchedulerException; /**
* 移除所有任务
*/
public void deleteAll() throws SchedulerException; /**
* 暂停任务
*
* @param jobName
* @param jobGroup
*/
public void pauseJob(String jobName, String jobGroup) throws SchedulerException; /**
* 暂停所有任务
*/
public void pauseAll() throws SchedulerException; /**
* 恢复某个任务
*
* @param jobName
* @param jobGroup
*/
public void resumeJob(String jobName, String jobGroup) throws SchedulerException; /**
* 恢复所有
*/
public void resumeAll() throws SchedulerException; /**
* 关闭任务调度器
*/
public void shutDown() throws SchedulerException; /**
* 开启任务调度器
*/
public void startScheduler() throws SchedulerException;
}

实现类:

//定义该bean的name为"quartzProducer"
@Service("quartzProducer")
public class QuartzProducerImpl implements QuartzProducer { //虽然在Spring配置中配置的是SchedulerFactoryBean这个类,但是我们自动转配就写这样,一样是可以使用的
@Autowired
private Scheduler scheduler; @Override
public void addSimpleJob(String jobName, String jobGroup, String className, String methodName, ArrayList paramArray, String runDateTime) throws SchedulerException, ParseException {
//判断是否已存在相同jobName,jobGroup,若存在则删除
if (scheduler.getJobDetail(JobKey.jobKey(jobName, jobGroup)) != null) {
deleteJob(jobName, jobGroup);
}
JobDetail jobDetail = JobBuilder.newJob(QuartzJobFactory.class).withIdentity(jobName, jobGroup).build();
//任务具体执行的内容封装,返回给job统一入口
ScheduleJob job = new ScheduleJob(jobName, jobGroup, jobName, jobGroup, className, methodName, paramArray, null, runDateTime, null);
//将我自定义的POJO类存放到DataMap中
jobDetail.getJobDataMap().put("scheduleJob", job);
//创建SimpleTrigger,在特定时间仅运行一次
Date runDate = DateUtils.parseDate(runDateTime, DateStyle.YYYYMMDDHHMMSS.getValue());
SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup).
startAt(runDate).build();
scheduler.scheduleJob(jobDetail, trigger);
} }
只贴了一个添加的方法,其他方法可以自行实现。注释应该比较清楚了,这里不过多赘述。
 
ok,到这里,我们已经完全了quartz跟spring的整合,以及如何调用service层的业务逻辑,任务的动态处理。
 
 
接下来就非常非常简单了,一般来说就是前端调用controller层,给它传参,比如要调用什么接口,接口的方法,jobname,jobgroup,方法参数,什么时候运行,或者是cron表达式。然后controller层再调用我们刚刚写的quartzProducer就可以了。
 
 
其他方法,比如定时任务修改,停用,删除,都是类似的,controller-->service
 
好了,大概的思路就是这样子,如果有什么不对的地方请拍砖,有什么不太清楚的地方也请拍砖!
 
 
 
 
 

Quartz-Spring定时任务器持久化,通过Service动态添加,删除,启动暂停任务的更多相关文章

  1. jquery动态添加删除div--事件绑定,对象克隆

    我想做一个可以动态添加删除div的功能.中间遇到一个问题,最后在manong123.com开发文摘 版主的热心帮助下解答了(答案在最后) 使用到的jquery方法和思想就是:事件的绑定和销毁(unbi ...

  2. 编辑 Ext 表格(一)——— 动态添加删除行列

    一.动态增删行 在 ext 表格中,动态添加行主要和表格绑定的 store 有关, 通过对 store 数据集进行添加或删除,就能实现表格行的动态添加删除.   (1) 动态添加表格的行  gridS ...

  3. 用Javascript动态添加删除HTML元素实例 (转载)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. js实现网页收藏功能,动态添加删除网址

    <html> <head> <title> 动态添加删除网址 </title> <meta charset="utf-8"&g ...

  5. jQuery动态添加删除CSS样式

    jQuery框架提供了两个CSS样式操作方法,一个是追加样式addClass,一个是移除样式removeClass,下面通过一个小例子讲解用法. jQuery动态追加移除CSS样式 <!DOCT ...

  6. JS动态添加删除html

    本功能要求是页面传一个List 集合给后台而且页面可以动态添加删除html代码需求如下: 下面是jsp页面代码 <%@ page language="java" pageEn ...

  7. C#控制IIS动态添加删除网站

    我的目的是在Winform程序里面,可以直接启动一个HTTP服务端,给下游客户连接使用. 查找相关技术,有两种方法: 1.使用C#动态添加网站应用到IIS中,借用IIS的管理能力来提供HTTP接口.本 ...

  8. Angular-表单动态添加删除

    angular本身不允许去操作DOM,在angular的角度来说,所有操作都以数据为核心,剩下的事情由angular来完成.所以说,想清楚问题的根源,解决起来也不是那么困难. 前提 那么,要做的这个添 ...

  9. jQuery动态添加删除select项

    // 添加 function col_add() { var selObj = $("#mySelect"); var value="value"; var t ...

随机推荐

  1. JavaScript or JQuery 获取服务器时间

    用js做时间校正,获取本机时间,是存在bug的. 使用js也可获取到服务器时间,原理是使用 ajax请求,返回的头部信息就含有服务器端的时间信息,获取到就可以了(有的IE下扔不会正常获取,还是更建议走 ...

  2. 特别篇:Hyper-v群集模拟实战演示

    介绍 由于前面几张的都是直接整理了下 九叔的hyper-v电子书发上来的,个人觉得他写的不是最详细,因此今天我按照自己的实际情况来写个模拟的实战演示.所有的东西都通过VMware WorkStatio ...

  3. MC9SD64单片机快速入门 I/O寄存器

    I/O的使用 数据方向寄存器和数据寄存器的配置 I/O输入输出的使用: 数据方向寄存器与数据寄存器 寄存器的概念: 寄存器,是集成电路中非常重要的一种存储单元,通常由触发器组成.在集成电路设计中,寄存 ...

  4. 第七章 LED将为我闪烁:控制发光二级管

    LED驱动开发实验 如图所示,LED1-LED2 分别与GPC0_3.GPC0_4 相连,通过GPC0_3.GPC0_4 引脚的高低电平来控制三极管的导通性,从而控制LED 的亮灭. 根据三极管的特性 ...

  5. February 21st, 2018 Week 8th Wednesday

    Our life is what our thoughts make it. 我们的思想成就了我们的生活. The mind is everything. What you think, you be ...

  6. vue开发常见命令

    1.安装脚手架 安装脚手架命令:npm install -global vue-cli 2.升级脚手架 有时候需要把整个脚手架升级一下,这个用到命令npm install --global vue-c ...

  7. #006 C语言大作业学生管理系统第三天

    还差最后两部分 读取文件 恢复删除的学生信息 先学会处理文件的 知识点,再继续跟着视频做这个作业. 应该明天周六能把视频里手把手教的学生管理系统敲完 第二周尽量自己能完成C语言课本最后面那道学生管理系 ...

  8. Thread.currentThread()和this的区别——《Java多线程编程核心技术》

    前言:在阅读<Java多线程编程核心技术>过程中,对书中程序代码Thread.currentThread()与this的区别有点混淆,这里记录下来,加深印象与理解. 具体代码如下: pub ...

  9. nginx学习笔记(一)

    select模型主要是apache用   FD 文件描述符   soa架构 安装nginx ping baidu.com netstat -lntup 查看端口 cat /etc/redhat-rel ...

  10. 正则表达式工具RegexBuddy

    1 下载 RegexBuddy 并安装 安装后的界面如下:     2 切换布局 点击右上角的彩色格子图标,选择 Side by Side Layout:     这种布局的好处是,Create 面板 ...