我想在我的彈簧啓動應用程序中使用彈簧批處理。我有一個用例來在一天中的某個時間段內停止工作,一旦時間窗口過去,我想從暫停的步驟重新開始工作。時至今日,我已經想通了,有如下圖所示類這樣的方法有兩種:春季批處理重啓持久存儲作業註冊作業
jobRepository和jobExplorer都是由永久存儲支持的class JobStarter {
@Autowired protected JobLauncher jobLauncher
@Autowired protected JobRegistry jobRegistry
@Autowired protected JobOperator jobOperator
@Autowired protected JobExplorer jobExplorer
def startJob(Map config) {
Job job = build(config, subject) // build the job programmatically
JobParameters jobParameters = createJobParameters(subject, config)
jobLauncher.launch (job, jobParameters)
jobRegistry.register(new ReferenceFactory(job))
}
def restartJob1(String jobName, JobParameters jobParameters) {
Job job = jobRegistry.getJob(jobName)
jobLauncher.launch (job, jobParameters)
}
// OR
def restartJob2(String jobName) {
def jobInstances = jobExplorer.getJobInstances(jobName, 0, 1)
if (!jobInstances) {
throw new Exception("Unable to find the job to restart")
}
def jobInstance = jobInstances[0]
jobOperator.restart(jobInstance.instanceId)
}
}
我有自定義實現。
我不能使用由Spring批處理提供的JobRegistry的默認實現,因爲它由內存映射支持,並且如果服務器關閉,jobRegistry爲空,因此重新啓動暫停的作業失敗。我想實現JobRegistry但問題是,我有一個困難時期我的自定義實現jobRegistry內持續工作的工廠:
class PersistentJobRegistry implements JobRegistry {
// Other methods and code omitted for brevity
static ObjectMapper mapper
static {
mapper = new ObjectMapper()
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
mapper.enableDefaultTyping()
}
@Override
void register(JobFactory jobFactory) throws DuplicateJobException {
String jobFactoryStr = mapper.writeValueAsString(jobFactory)
save(jobFactory.getJobName(), jobFactoryStr) // saves jobFactoryStr to store
}
@Override
Job getJob(String name) throws NoSuchJobException {
String jobFactoryStr = get(name) // gets a serialized factory from store
JobFactory jobFactory = mapper.readValue(jobFactoryStr, JobFactory.class)
return jobFactory.createJob()
}
}
同時節約,我拿這個作爲jobFactoryStr,這顯然不會工作,因爲只有JOBNAME和有關作業沒有其他的信息和它的步驟:
jobFactoryStr = {"jobName":"MyJob:f6892e89-4a76-4395-ba0a-ca82b477a407"}
我得到以下錯誤getJob()太:
com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class org.springframework.batch.core.configuration.JobFactory
at [Source: {"jobName":"Pipeline:api:testing:c3241e19-4f32-474f-90d2-2974b672c183"}; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:854)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:122)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:93)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:58)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserializeWithType(AbstractDeserializer.java:132)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:41)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2161)
我有兩個問題:
是我重新開始工作正確的做法?
我的jobRegistry實現方法是否正確?以上傑克遜錯誤會發生什麼問題?
「JobRegistry」從哪裏啓動? – 2015-02-11 17:24:01
@Michael,它是在spring中注入的,因爲一個bean(實現MapJobRegistry的東西存在於spring-batch jar中)。你在問什麼? – user788052 2015-02-12 00:00:17
我問,因爲你說你不能使用基於地圖的註冊表,因爲如果服務器崩潰它將是空的。我假設在重新啓動時註冊表將被重新填充,以便在不需要持久性的情況下恢復狀態。 – 2015-02-12 16:57:33