我正在做我的毕业设计,并且在这里陷入了两难境地。 我需要创建一个生成PDF的应用程序,并按照数据库中的数据定义的计划将它们通过电子邮件发送给人们。 我正在为这个项目的公司工作,我们已经有了一个我们使用的GlassFish应用服务器。如果整个解决方案都像现在一样在一个包中交付,那将是最好的。 客户端使用webstart Web应用程序等都在一个包中
我的新服务需要在单独的线程上运行,生成报告并通过电子邮件发送出去。从我在网上看到的内容来看,在GlassFish中非常不鼓励在应用服务器中运行自己的线程,所以听起来我需要创建自己独立的应用程序。
这真的可以吗?您对此有何评论,最佳做法是什么?
答案 0 :(得分:5)
<强> @Schedule 强>
如果您使用的是Ejb 3.1(glassfish 3.x),则可以使用@Schedule注释让容器在指定的时间间隔或给定的日历时间内调用方法。允许您避免在自己的代码中处理线程
@Stateless
public class LabbBean {
@EJB
WorkerEjb workerEjb;
@Schedule(second="*/5", minute="*",hour="*", persistent=false)
public void myMethod() {
for (all jobs found in db){
workerEjb.workerMethod(job);
}
}
}
@Stateless
public class WorkerEjb {
@Asynchronous
public void workerMethod(job) {
//Send emails
}
}
如果你想在不同的线程中完成工作,那么@Schedule带注释的方法可以使用注释为@Asynchronous的worker-method调用worker-ejb
<强> @Timeout 强>
我刚刚意识到您希望从数据库启动计划。一个选项是使用@Singleton ejb和@Startup注释以编程方式启动一组计时器。如果某些定时器同时耗尽,则会在单独的线程中调用超时注释方法。
@Singleton
@Startup
public class LabbBean {
@Resource
protected TimerService timerService;
@PostConstruct
public void init() {
//Init your timers from the data in the database here
for (all your timers) {
TimerConfig config = new TimerConfig();
config.setInfo("timer1");
config.setPersistent(false);
ScheduleExpression schedule = new ScheduleExpression();
schedule.dayOfMonth(10);
schedule.minute(2);
timerService.createCalendarTimer(schedule, config);
}
}
//method called when timeout occurs
@Timeout
public void timeoutHandler(Timer timer) {
String name = timer.getInfo().toString();
System.out.println("Timer name=" + name);
}
}