play framework call WS里面的Scheduled asynchronous tasks
play framework call WS inside Scheduled asynchronous tasks
我正在开始使用 play framework 我想编写一个可以进行一定数量的 ws 调用的作业。
我写了 2 类 如下:
@Singleton
public class AutoGateJob {
@Inject
private ActorSystem actorSystem;
@Inject
private ExecutionContext executionContext;
@Inject
private RgsDataServiceServices rgsDataServiceServices;
@Inject
public AutoGateJob(ApplicationLifecycle lifecycle, ActorSystem system, ExecutionContext
context) {
Logger.info("### create autojob");
this.actorSystem = system;
this.executionContext = context;
this.initialize();
lifecycle.addStopHook(() -> {
Logger.info("### c'est l'heure de rentrer!!!");
this.actorSystem.shutdown();
return CompletableFuture.completedFuture(null);
});
}
private void initialize() {
this.actorSystem.scheduler().schedule(
Duration.create(0, TimeUnit.SECONDS), // initialDelay
Duration.create(5, TimeUnit.SECONDS), // interval
() -> this.runAutoGateJobTasks(),
this.executionContext
);
}
private void runAutoGateJobTasks() {
Logger.info("## Run job every 5 seconds");
rgsDataServiceServices = new RgsDataServiceServices();
rgsDataServiceServices.findAllPaymentToSendHandler()
.handle((wsResponse, throwable) -> {
Logger.info("## find all payment to send response: ", wsResponse.asJson());
List<String> paymentsList = new ArrayList<>();
paymentsList.forEach(s -> {
Logger.info("## Processing payment: ", s);
});
return CompletableFuture.completedFuture(null);
});
}
}
和
public class AutoGateJobInitializer extends AbstractModule {
@Override
protected void configure() {
Logger.info("## Setup job on app startup!");
bind(AutoGateJob.class).asEagerSingleton();
}
}
问题是:
我的 rgsDataServiceServices 有一个有效的 WSClient 注入,当与控制器一起使用时效果很好,但在 AutoGateJob 中调用时我有空指针异常
(
[错误] a.d.TaskInvocation - 空
java.lang.NullPointerException:空
)
我真的不明白发生了什么,但我需要我的工作以这种方式行事。
感谢您的帮助!
您应该将所有依赖项注入构造函数。您所做的只是在构造函数中注入一些,然后您立即安排一个尝试使用所有依赖项的任务,但有可能,该任务将 运行 在 Guice 注入所有依赖项之前。如果你想确保你所有的依赖都可用,只使用构造函数注入,即:
private final ActorSystem actorSystem;
private final ExecutionContext executionContext;
private final RgsDataServiceServices rgsDataServiceServices;
@Inject
public AutoGateJob(ActorSystem system, ExecutionContext context, RgsDataServiceServices rgsDataServiceServices) {
Logger.info("### create autojob");
this.actorSystem = system;
this.executionContext = context;
this.rgsDataServiceServices = rgsDataServiceServices
this.initialize();
}
此外,您不应该添加生命周期挂钩来关闭 actor 系统,Play 已经注册了生命周期挂钩来执行此操作。如果你愿意,你可以注册一个生命周期钩子来取消计划任务,但我认为这不是真的有必要,因为它会在actor系统关闭时自动取消。
我正在开始使用 play framework 我想编写一个可以进行一定数量的 ws 调用的作业。
我写了 2 类 如下:
@Singleton
public class AutoGateJob {
@Inject
private ActorSystem actorSystem;
@Inject
private ExecutionContext executionContext;
@Inject
private RgsDataServiceServices rgsDataServiceServices;
@Inject
public AutoGateJob(ApplicationLifecycle lifecycle, ActorSystem system, ExecutionContext
context) {
Logger.info("### create autojob");
this.actorSystem = system;
this.executionContext = context;
this.initialize();
lifecycle.addStopHook(() -> {
Logger.info("### c'est l'heure de rentrer!!!");
this.actorSystem.shutdown();
return CompletableFuture.completedFuture(null);
});
}
private void initialize() {
this.actorSystem.scheduler().schedule(
Duration.create(0, TimeUnit.SECONDS), // initialDelay
Duration.create(5, TimeUnit.SECONDS), // interval
() -> this.runAutoGateJobTasks(),
this.executionContext
);
}
private void runAutoGateJobTasks() {
Logger.info("## Run job every 5 seconds");
rgsDataServiceServices = new RgsDataServiceServices();
rgsDataServiceServices.findAllPaymentToSendHandler()
.handle((wsResponse, throwable) -> {
Logger.info("## find all payment to send response: ", wsResponse.asJson());
List<String> paymentsList = new ArrayList<>();
paymentsList.forEach(s -> {
Logger.info("## Processing payment: ", s);
});
return CompletableFuture.completedFuture(null);
});
}
}
和
public class AutoGateJobInitializer extends AbstractModule {
@Override
protected void configure() {
Logger.info("## Setup job on app startup!");
bind(AutoGateJob.class).asEagerSingleton();
}
}
问题是: 我的 rgsDataServiceServices 有一个有效的 WSClient 注入,当与控制器一起使用时效果很好,但在 AutoGateJob 中调用时我有空指针异常 ( [错误] a.d.TaskInvocation - 空 java.lang.NullPointerException:空 ) 我真的不明白发生了什么,但我需要我的工作以这种方式行事。
感谢您的帮助!
您应该将所有依赖项注入构造函数。您所做的只是在构造函数中注入一些,然后您立即安排一个尝试使用所有依赖项的任务,但有可能,该任务将 运行 在 Guice 注入所有依赖项之前。如果你想确保你所有的依赖都可用,只使用构造函数注入,即:
private final ActorSystem actorSystem;
private final ExecutionContext executionContext;
private final RgsDataServiceServices rgsDataServiceServices;
@Inject
public AutoGateJob(ActorSystem system, ExecutionContext context, RgsDataServiceServices rgsDataServiceServices) {
Logger.info("### create autojob");
this.actorSystem = system;
this.executionContext = context;
this.rgsDataServiceServices = rgsDataServiceServices
this.initialize();
}
此外,您不应该添加生命周期挂钩来关闭 actor 系统,Play 已经注册了生命周期挂钩来执行此操作。如果你愿意,你可以注册一个生命周期钩子来取消计划任务,但我认为这不是真的有必要,因为它会在actor系统关闭时自动取消。