如何使用 EJB 实现永久后台进程?
How to implement a permanent background process with EJBs?
我对 EJB 中的通用设计模式有疑问。我有 Java EE 应用程序(EJB 和 Web),我需要一种通过 JPA 永久扫描和处理特定数据的后台进程。
我想到的一个解决方案是实现@Singleton EJB。在用 @PostConstruct 注释的方法中,我可以开始我的过程。
@Singleton
@Startup
public class MyUpdateService {
@PostConstruct
void init() {
while(true) {
// scann for new data...
// do the job.....
}
}
}
但这是推荐的模式吗?还是有更好的方法在 EJB 容器中 运行 这样的 class?
在 EJB 中还有其他模式,如 @TimerService 和新的 Java EE7 批处理。但是我认为这两个概念都用于有限过程?
在当前项目中使用 EJB TimerService 执行周期性数据修剪或后端数据同步等任务。它不仅允许单次执行,还允许间隔计时器和基于日历的计时器。
像:
@Startup
@Singleton
public class SyncTimer {
private static final long HOUR = 60 * 60 * 1000L;
@Resource
private TimerService timerService;
private Timer timer;
@PostConstruct
public void init() {
TimerConfig config = new TimerConfig();
config.setPersistent(false);
timer = timerService.createIntervalTimer(HOUR, HOUR, config);
}
@Timeout
private synchronized void onTimer() {
// every hour action
}
}
自 Java EE 7 起,@devmind 提到的 TimerSerivce 的替代方案可以使用 ManagedScheduledExecutorService:
@Startup
@Singleton
public class Scheduler {
static final long INITIAL_DELAY = 0;
static final long PERIOD = 2;
@Resource
ManagedScheduledExecutorService scheduler;
@PostConstruct
public void init() {
this.scheduler.scheduleAtFixedRate(this::invokePeriodically,
INITIAL_DELAY, PERIOD,
TimeUnit.SECONDS);
}
public void invokePeriodically() {
System.out.println("Don't use sout in prod " + LocalTime.now());
}
}
与 TimerSerivce 不同,ExecutorService 可以 运行 在单独的任务中并行。另见 blog post form Adam Bien。
我对 EJB 中的通用设计模式有疑问。我有 Java EE 应用程序(EJB 和 Web),我需要一种通过 JPA 永久扫描和处理特定数据的后台进程。
我想到的一个解决方案是实现@Singleton EJB。在用 @PostConstruct 注释的方法中,我可以开始我的过程。
@Singleton
@Startup
public class MyUpdateService {
@PostConstruct
void init() {
while(true) {
// scann for new data...
// do the job.....
}
}
}
但这是推荐的模式吗?还是有更好的方法在 EJB 容器中 运行 这样的 class?
在 EJB 中还有其他模式,如 @TimerService 和新的 Java EE7 批处理。但是我认为这两个概念都用于有限过程?
在当前项目中使用 EJB TimerService 执行周期性数据修剪或后端数据同步等任务。它不仅允许单次执行,还允许间隔计时器和基于日历的计时器。
像:
@Startup
@Singleton
public class SyncTimer {
private static final long HOUR = 60 * 60 * 1000L;
@Resource
private TimerService timerService;
private Timer timer;
@PostConstruct
public void init() {
TimerConfig config = new TimerConfig();
config.setPersistent(false);
timer = timerService.createIntervalTimer(HOUR, HOUR, config);
}
@Timeout
private synchronized void onTimer() {
// every hour action
}
}
自 Java EE 7 起,@devmind 提到的 TimerSerivce 的替代方案可以使用 ManagedScheduledExecutorService:
@Startup
@Singleton
public class Scheduler {
static final long INITIAL_DELAY = 0;
static final long PERIOD = 2;
@Resource
ManagedScheduledExecutorService scheduler;
@PostConstruct
public void init() {
this.scheduler.scheduleAtFixedRate(this::invokePeriodically,
INITIAL_DELAY, PERIOD,
TimeUnit.SECONDS);
}
public void invokePeriodically() {
System.out.println("Don't use sout in prod " + LocalTime.now());
}
}
与 TimerSerivce 不同,ExecutorService 可以 运行 在单独的任务中并行。另见 blog post form Adam Bien。