我有一个Java,Spring应用程序,我在其中安排了一些报告作业。该组件如下所示:
@Component
public class RegisterReportSchedules implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private ThreadPoolTaskScheduler ts;
private List<String> reportSchedules; //contains list of report schedules
@Autowired
private SomeTask sometask;
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
reportSchedules.forEach((String schedule) -> {
ReportSchedule reportSchedule = new ReportSchedule(schedule,
propertiesUtil.getProperty(schedule + "." + Constants.CRON));
ts.schedule(new ReportTask(reportSchedule),
new CronTrigger(reportSchedule.getCronExpression()));
});
}
class ReportTask implements Runnable {
private ReportSchedule schedule;
public ReportTask(ReportSchedule schedule) {
this.schedule = schedule;
}
@Override
public void run() {
sometask.process(schedule);
}
}
}
假设我有 5reportSchedules
要处理。完成所有 5ReportTasks
后,我需要在数据库表中写入一个条目,说所有报告任务都已完成。
但是,如何跟踪有关我的应用程序中完成的每个报告计划的信息?
我是否需要为每个完成的计划写入数据库表,或者Spring
中是否有更好的替代方案将触发某种通知事件,然后我可以使用该事件将ALL COMPLETED
事件写入表?如果给出一些带有示例的答案,请表示感谢。
由于您不需要跟踪reportSchedules
,我很想做这样的事情:
- 移动以使用
Queue
,以便在poll
时删除String
。 - 跟踪您提交的任务数。(*)
- 添加一个自定义
ApplicationEvent
类型的ReportScheduleProcessedEvent
(或类似(,并在ReportTask
的run
方法末尾发布其中一个(到Spring的ApplicationEventPublisher
(。 - 为此类型添加一个新
ApplicationListener
,它会等到它收到的事件数与您在 (*( 中跟踪的事件一样多;然后将某些内容发布到数据库。
恐怕我在这里没有提供任何代码,因为您可能需要也可能不需要关心上面的一堆点的线程安全性,并且适当地处理这个问题可能不是一件小事。
编辑;每个请求样本的注释。 我假设你至少使用的是 Spring 4.3。
编辑编辑:每条评论。
abstract class ReportScheduleEvent extends ApplicationEvent { ... }
public class IncomingReportCompletionEvent
extends ReportScheduleEvent {
private final int eventsToExpect;
// ...
}
public class ReportCompletionEvent extends ReportSchedulingEvent {
// ...
}
public class YourListener
implements ApplicationListener<ReportSchedulingEvent> {
private final DatabaseWriter dbWriter;
private volatile int expectedEvents = 0;
public void onApplicationEvent(final ReportSchedulingEvent event) {
if (event instanceof IncomingReportCompletionEvent) {
this.expectedEvents =
((IncomingReportCompletionEvent) event)
.getExpectedEventCount();
} else {
this.expectedEvents--;
if (this.expectedEvents == 0) {
this.dbWriter.doYourThing();
}
}
}
}