GlassFish服务器上的单独线程

And*_*ock 3 java service glassfish java-ee

我正在做毕业设计,在这里遇到了难题。我需要制作一个生成PDF并按数据库中数据定义的时间表通过电子邮件将其发送给人们的应用程序。我正在为此项目的公司工作,我们已经有一个使用的GlassFish应用程序服务器。最好是像现在这样将整个解决方案打包在一个软件包中交付。带有webstart Web应用程序等的客户端都在一个软件包中

我的新服务需要在单独的线程上运行,生成报告并通过电子邮件发送出去。从Web上可以阅读的内容来看,强烈建议不要使用GlassFish在应用程序服务器中运行自己的线程,因此听起来我需要制作自己的独立应用程序。

真的可以吗?您对此有何评论?最佳实践是什么?

Aks*_*ert 5

@时间表

如果您使用的是Ejb 3.1(glassfish 3.x),则可以使用@Schedule批注,以使容器以指定的间隔或在给定的日历时间调用方法。允许您避免在自己的代码中处理线程

了解有关ejb 3.1计时器的信息

@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
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您想在单独的线程中完成工作,则@Schedule注释方法可以调用worker-ejb,并将worker方法注释为@Asynchronous

@超时

我刚刚意识到您希望从数据库启动计划。一种选择是使用带有@Startup批注的@Singleton ejb以编程方式启动一堆计时器。如果某些计时器同时用完,则将在单独的线程中调用带有超时注释的方法。

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)