1.简单介绍

Quarz.Net中采用插件式来实现配置文件配置,通过XMLSchedulingDataProcessor类进行Xml数据处理

默认配置文件命名:quart_jobs.xml

public const string QuartzXmlFileName = "quartz_jobs.xml";

2.创建配置

首先安装扩展程序:Liquid XML Objects(基于XML的xsd文件创建数据模型)

 新建quartz_jobs.xml文件,选择XML=>Schemas 

 Add

 quartz_jobs.xml

<?xml version="1.0" encoding="utf-8" ?>
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData">
<processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives> <schedule>
<job>
<name>myJob</name>
<group>aaron</group>
<description>这是Xml定义的Job</description>
<job-type>Quartz_Demo.MyJob,Quartz_Demo</job-type>
<durable>true</durable>
<recover>true</recover>
<job-data-map>
<entry>
<key>myKey</key>
<value>myValue</value>
</entry>
</job-data-map>
</job>
<trigger>
<simple>
<name>myTrigger</name>
<description>这是Xml定义的Trigger</description>
<job-name>myJob</job-name>
<job-group>aaron</job-group>
<repeat-count>-1</repeat-count>
<repeat-interval>1000</repeat-interval>
</simple>
</trigger>
</schedule>
</job-scheduling-data>

安装Quartz.Plugins包

编写代码

            var assemblyName = typeof(Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin).AssemblyQualifiedName;

            var scheduler= await SchedulerBuilder.Create().UseXmlSchedulingConfiguration((options)=>{
options.SetProperty("quartz.plugin.xml.fileNames", "quartz_jobs.xml");
options.SetProperty("quartz.plugin.xml.scanInterval", "");
options.SetProperty("quartz.threadPool.threadCount", "");
}).Build(); //System.Collections.Specialized.NameValueCollection collection = new System.Collections.Specialized.NameValueCollection(); //collection.Add("quartz.plugin.xml.type", assemblyName); //collection.Add("quartz.plugin.xml.fileNames","quartz_jobs.xml"); //collection.Add("quartz.plugin.xml.scanInterval", "10"); //var factory = new StdSchedulerFactory(collection); //var scheduler = await factory.GetScheduler(); LogProvider.SetCurrentLogProvider(new ConsoleLogProvider()); await scheduler.Start(); var metaData=await scheduler.GetMetaData(); Console.WriteLine(metaData.ThreadPoolSize);

自定义LogPrivider

    public class ConsoleLogProvider : ILogProvider
{
public Logger GetLogger(string name)
{
Logger loger = (logLevel, messageFunc, exception, formatParameters) =>
{
if (logLevel >= LogLevel.Debug && messageFunc != null)
{
Console.WriteLine("[" + DateTime.Now.ToLongTimeString() + "] [" + logLevel + "] " + messageFunc(), formatParameters);
}
return true;
}; return loger;
} public IDisposable OpenMappedContext(string key, object value, bool destructure = false)
{
return null;
} public IDisposable OpenNestedContext(string message)
{
return null;
}
}

运行图

 源码解析

 foreach (jobdetailType jobDetailType in jobNodes)
{
string jobName = jobDetailType.name.TrimEmptyToNull();
string jobGroup = jobDetailType.group.TrimEmptyToNull();
string jobDescription = jobDetailType.description.TrimEmptyToNull();
string jobTypeName = jobDetailType.jobtype.TrimEmptyToNull();
bool jobDurability = jobDetailType.durable;
bool jobRecoveryRequested = jobDetailType.recover; Type jobType = TypeLoadHelper.LoadType(jobTypeName); IJobDetail jobDetail = JobBuilder.Create(jobType)
.WithIdentity(jobName, jobGroup)
.WithDescription(jobDescription)
.StoreDurably(jobDurability)
.RequestRecovery(jobRecoveryRequested)
.Build(); if (jobDetailType.jobdatamap != null && jobDetailType.jobdatamap.entry != null)
{
foreach (entryType entry in jobDetailType.jobdatamap.entry)
{
string key = entry.key.TrimEmptyToNull();
string value = entry.value.TrimEmptyToNull();
jobDetail.JobDataMap.Add(key, value);
}
} if (Log.IsDebugEnabled())
{
Log.Debug("Parsed job definition: " + jobDetail);
} AddJobToSchedule(jobDetail);
} //
// Extract Trigger definitions...
// List<triggerType> triggerEntries = new List<triggerType>();
if (data.schedule != null)
{
foreach (var schedule in data.schedule)
{
if (schedule != null && schedule.trigger != null)
{
triggerEntries.AddRange(schedule.trigger);
}
}
} Log.Debug("Found " + triggerEntries.Count + " trigger definitions."); foreach (triggerType triggerNode in triggerEntries)
{
string triggerName = triggerNode.Item.name.TrimEmptyToNull();
string triggerGroup = triggerNode.Item.group.TrimEmptyToNull();
string triggerDescription = triggerNode.Item.description.TrimEmptyToNull();
string triggerCalendarRef = triggerNode.Item.calendarname.TrimEmptyToNull();
string triggerJobName = triggerNode.Item.jobname.TrimEmptyToNull();
string triggerJobGroup = triggerNode.Item.jobgroup.TrimEmptyToNull(); int triggerPriority = TriggerConstants.DefaultPriority;
if (!triggerNode.Item.priority.IsNullOrWhiteSpace())
{
triggerPriority = Convert.ToInt32(triggerNode.Item.priority);
} DateTimeOffset triggerStartTime = SystemTime.UtcNow();
if (triggerNode.Item.Item != null)
{
if (triggerNode.Item.Item is DateTime time)
{
triggerStartTime = new DateTimeOffset(time);
}
else
{
triggerStartTime = triggerStartTime.AddSeconds(Convert.ToInt32(triggerNode.Item.Item));
}
} DateTime? triggerEndTime = triggerNode.Item.endtimeSpecified ? triggerNode.Item.endtime : (DateTime?) null; IScheduleBuilder sched; if (triggerNode.Item is simpleTriggerType simpleTrigger)
{
string repeatCountString = simpleTrigger.repeatcount.TrimEmptyToNull();
string repeatIntervalString = simpleTrigger.repeatinterval.TrimEmptyToNull(); int repeatCount = ParseSimpleTriggerRepeatCount(repeatCountString);
TimeSpan repeatInterval = repeatIntervalString == null ? TimeSpan.Zero : TimeSpan.FromMilliseconds(Convert.ToInt64(repeatIntervalString)); sched = SimpleScheduleBuilder.Create()
.WithInterval(repeatInterval)
.WithRepeatCount(repeatCount); if (!simpleTrigger.misfireinstruction.IsNullOrWhiteSpace())
{
((SimpleScheduleBuilder) sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(simpleTrigger.misfireinstruction));
}
}
else if (triggerNode.Item is cronTriggerType)
{
cronTriggerType cronTrigger = (cronTriggerType) triggerNode.Item;
string cronExpression = cronTrigger.cronexpression.TrimEmptyToNull();
string timezoneString = cronTrigger.timezone.TrimEmptyToNull(); TimeZoneInfo tz = timezoneString != null ? TimeZoneUtil.FindTimeZoneById(timezoneString) : null;
sched = CronScheduleBuilder.CronSchedule(cronExpression)
.InTimeZone(tz); if (!cronTrigger.misfireinstruction.IsNullOrWhiteSpace())
{
((CronScheduleBuilder) sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(cronTrigger.misfireinstruction));
}
}
else if (triggerNode.Item is calendarIntervalTriggerType)
{
calendarIntervalTriggerType calendarIntervalTrigger = (calendarIntervalTriggerType) triggerNode.Item;
string repeatIntervalString = calendarIntervalTrigger.repeatinterval.TrimEmptyToNull(); IntervalUnit intervalUnit = ParseDateIntervalTriggerIntervalUnit(calendarIntervalTrigger.repeatintervalunit.TrimEmptyToNull());
int repeatInterval = repeatIntervalString == null ? : Convert.ToInt32(repeatIntervalString); sched = CalendarIntervalScheduleBuilder.Create()
.WithInterval(repeatInterval, intervalUnit); if (!calendarIntervalTrigger.misfireinstruction.IsNullOrWhiteSpace())
{
((CalendarIntervalScheduleBuilder) sched).WithMisfireHandlingInstruction(ReadMisfireInstructionFromString(calendarIntervalTrigger.misfireinstruction));
}
}
else
{
throw new SchedulerConfigException("Unknown trigger type in XML configuration");
} IMutableTrigger trigger = (IMutableTrigger) TriggerBuilder.Create()
.WithIdentity(triggerName, triggerGroup)
.WithDescription(triggerDescription)
.ForJob(triggerJobName, triggerJobGroup)
.StartAt(triggerStartTime)
.EndAt(triggerEndTime)
.WithPriority(triggerPriority)
.ModifiedByCalendar(triggerCalendarRef)
.WithSchedule(sched)
.Build(); if (triggerNode.Item.jobdatamap != null && triggerNode.Item.jobdatamap.entry != null)
{
foreach (entryType entry in triggerNode.Item.jobdatamap.entry)
{
string key = entry.key.TrimEmptyToNull();
string value = entry.value.TrimEmptyToNull();
trigger.JobDataMap.Add(key, value);
}
} if (Log.IsDebugEnabled())
{
Log.Debug("Parsed trigger definition: " + trigger);
} AddTriggerToSchedule(trigger);
}

Quartz.Net系列(十六):通过Plugins模式使用Xml方式配置Job和Trigger和自定义LogPrivider的更多相关文章

  1. S3C2416裸机开发系列十六_sd卡驱动实现

    S3C2416裸机开发系列十六 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.传输数据快.可插拔.安全性好等长 ...

  2. MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息

    MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二 ...

  3. Spring系列之aAOP AOP是什么?+xml方式实现aop+注解方式实现aop

    Spring系列之aop aop是什么?+xml方式实现aop+注解方式实现aop 什么是AOP? AOP为Aspect Oriented Programming 的缩写,意识为面向切面的编程,是通过 ...

  4. 学习ASP.NET Core Razor 编程系列十六——排序

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  5. 为什么不让用join?《死磕MySQL系列 十六》

    大家好,我是咔咔 不期速成,日拱一卒 在平时开发工作中join的使用频率是非常高的,很多SQL优化博文也让把子查询改为join从而提升性能,但部分公司的DBA又不让用,那么使用join到底有什么问题呢 ...

  6. Spring Boot2 系列教程(十六)定时任务的两种实现方式

    在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Qua ...

  7. 十六、Spring Boot 部署与服务配置

    spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项 ...

  8. SpringBoot填坑系列---XML方式配置数据库

    本次只是简单的运用SpringBoot搭建框架,对其原理并不做深入的探究 1.POM文件 <?xml version="1.0" encoding="UTF-8&q ...

  9. webpack4 系列教程(十六):开发模式和生产模式·实战

    好文章 https://www.jianshu.com/p/f2d30d02b719

随机推荐

  1. foreach 集合又抛经典异常了,这次一定要刨根问底

    一:背景 1. 讲故事 最近同事在写一段业务逻辑的时候,程序跑起来总是报:集合已修改:可能无法执行枚举操作,硬是没有找到什么情况下会导致这个异常产生,就让我来找一下bug,其实这个异常在座的每个程序员 ...

  2. WPF入门(2)——依赖属性

    今天我们说说依赖属性 什么是依赖属性? 当然,学术定义依旧Please Baidu:https://baike.baidu.com/item/%E4%BE%9D%E8%B5%96%E5%B1%9E%E ...

  3. 【Python爬虫】HTTP基础和urllib库、requests库的使用

    引言: 一个网络爬虫的编写主要可以分为三个部分: 1.获取网页 2.提取信息 3.分析信息 本文主要介绍第一部分,如何用Python内置的库urllib和第三方库requests库来完成网页的获取.阅 ...

  4. Beta冲刺--项目测试

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta 冲刺 这个作业的目标 Beta冲刺--项目测试 作业正文 如下 其他参考文献 ... Beta冲刺 ...

  5. 并发编程-CPU执行volatile原理探讨-可见性与原子性的深入理解

    volatile的定义 Java语言规范第3版中对volatile的定义如下:Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量.Jav ...

  6. .net core 静态类获取appsettings

    注入获取 通过IConfiguration直接获取的方法官方文档里就有,可以直接看这里 如:appsettings.json { "Position": { "Title ...

  7. 入门大数据---Hbase是什么?

    一.Hbase是什么? Hbase属于NoSql的一种. NoSql数据库分为如下几类: Key-Value类型数据库 这类数据库主要会使用到一个哈希表,这个表有一个特定的键和一个指针指向特定的数据. ...

  8. 入门大数据---Redis集群分布式学习

    Redis是什么? 官方介绍: Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件. 它支持多种类型的数据结构,如 字符串(strings), 散列( ...

  9. 重学 Java 设计模式:实战中介者模式「按照Mybaits原理手写ORM框架,给JDBC方式操作数据库增加中介者场景」

    作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 同龄人的差距是从什么时候拉开的 同样的幼儿园.同样的小学.一样 ...

  10. could not resolve property(无法解析属性)

    could not resolve property(无法解析属性) 顾名思义在写hql语句的时候,属性写错了! 请检查大小写,是实体类的,不是数据库表的! 一个一个检查,仔细看!