提示 对于新项目,推荐使用 JSON 作为数据库中存储数据的持久化格式。同时,强烈建议将
useProperties
设置为true
以限制键值仅为字符串类型。
Quartz.Serialization.Json 提供了使用 Json.NET 处理实际序列化过程的作业存储 JSON 序列化支持。
安装
需要在使用 Quartz 的项目中添加 NuGet 包引用。
Install-Package Quartz.Serialization.Json
配置
经典属性配置方式
var properties = new NameValueCollection
{
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", // "json" 是 "Quartz.Simpl.JsonObjectSerializer, Quartz.Serialization.Json" 的别名
["quartz.serializer.type"] = "json"
};
ISchedulerFactory schedulerFactory = new StdSchedulerFactory(properties);
使用调度器构建器配置
var config = SchedulerBuilder.Create();
config.UsePersistentStore(store =>
{
// 通常建议坚持使用字符串类型的属性键和值进行序列化
store.UseProperties = true;
store.UseGenericDatabase(dbProvider, db => db.ConnectionString = "我的连接字符串");
store.UseJsonSerializer();
});
ISchedulerFactory schedulerFactory = config.Build();
从二进制序列化迁移到 JSON
虽然没有官方的迁移解决方案,因为每个设置都可能有其特殊性,但存在一个可能适用于您的迁移方案。
- 配置如下面的
MigratorSerializer
这样的自定义序列化器,它能读取二进制序列化格式并以 JSON 格式写入。 - 让系统在运行过程中逐渐迁移,或者创建一个程序加载并把所有相关的序列化资产写回到数据库中。
示例混合序列化器
public class MigratorSerializer : IObjectSerializer
{
private BinaryObjectSerializer binarySerializer;
private JsonObjectSerializer jsonSerializer;
public MigratorSerializer()
{
this.binarySerializer = new BinaryObjectSerializer();
// you might need custom configuration, see sections about customizing
// in documentation
this.jsonSerializer = new JsonObjectSerializer();
}
public T DeSerialize<T>(byte[] data) where T : class
{
try
{
// Attempt to deserialize data as JSON
var result = this.jsonSerializer.DeSerialize<T>(data);
return result;
}
catch (JsonReaderException)
{
// Presumably, the data was not JSON, we instead use the binary serializer
return this.binarySerializer.DeSerialize<T>(data);
}
}
public void Initialize()
{
this.binarySerializer.Initialize();
this.jsonSerializer.Initialize();
}
public byte[] Serialize<T>(T obj) where T : class
{
return this.jsonSerializer.Serialize<T>(obj);
}
}
自定义 JSON.NET
如果您需要自定义 JSON.NET 设置,需要继承自定义实现并覆盖 CreateSerializerSettings
方法。
class CustomJsonSerializer : JsonObjectSerializer
{
protected override JsonSerializerSettings CreateSerializerSettings()
{
var settings = base.CreateSerializerSettings();
settings.Converters.Add(new MyCustomConverter());
return settings;
}
}
然后配置使用
store.UseSerializer<CustomJsonSerializer>(); // 或者配置为 "quartz.serializer.type" = "MyProject.CustomJsonSerializer, MyProject"
自定义日历序列化
如果您实现了自定义日历,需要为其实现 ICalendarSerializer
。有一个便利的基类 CalendarSerializer
可以帮助您获得强类型体验。
自定义日历及序列化器
[Serializable]
class CustomCalendar : BaseCalendar
{
public CustomCalendar(){}
protected CustomCalendar(SerializationInfo info, StreamingContext context) : base(info, context)
{
SomeCustomProperty = info?.GetBoolean("SomeCustomProperty") ?? true;
}
public bool SomeCustomProperty { get; set; } = true;
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info?.AddValue("SomeCustomProperty", SomeCustomProperty);
}
// JSON 序列化支持
class CustomCalendarSerializer : CalendarSerializer<CustomCalendar>
{
protected override CustomCalendar Create(JObject source)
{
return new CustomCalendar();
}
protected override void SerializeFields(JsonWriter writer, CustomCalendar calendar)
{
writer.WritePropertyName("SomeCustomProperty");
writer.WriteValue(calendar.SomeCustomProperty);
}
protected override void DeserializeFields(CustomCalendar calendar, JObject source)
{
calendar.SomeCustomProperty = source["SomeCustomProperty"]!.Value<bool>();
}
}
}
配置自定义日历序列化器
var config = SchedulerBuilder.Create();
config.UsePersistentStore(store =>
{
store.UseJsonSerializer(json => json.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer()));
});
// 或全局配置,上述代码实质上也是调用了
JsonObjectSerializer.AddCalendarSerializer<CustomCalendar>(new CustomCalendarSerializer());