使EJB @Schedule内部的方法仅被调用一次

问题描述 投票:0回答:1

所以我有一个相对简单的EJB。我想每隔十秒钟检查一次特定位置的pdf文件,并在发现它时发送邮件。可以正常工作并按预期工作,但我总是收到两封相同的电子邮件,而不是一封。代码如下:

@Stateless
public class TimerBean {

    private EmailService emailService ;
    private boolean fileNotFound;

    public TimerBean(){
       this.fileNotFound= true;
       emailService = new EmailService();
    }

    @Schedule(second = "*/10", minute = "*", hour = "*")
    public void searchForPdf(){
       PDFChecker pdfChecker = new PDFChecker("directoryPath");
       String pdf =  pdfChecker.getPdfFile();
       processSendMail(pdf);
    }

    private void processSendMail(String pdf){
        if (!pdf.equals("") & this.fileNotFound){
            this.fileNotFound= false;
            emailService.sendMail("dummyMail", "Dummy", "Pdf Found "+pdf);
        } 
    }
}

processSendMail方法执行两次,然后this.fileNotFound停留在true。我收到2封电子邮件,然后将this.fileNotFound设置为false。我尝试使用AtomicBoolean并将Bean @Singleton(或@Lock(LockType.Write)设为摘要here)。我在做错什么,以及如何使此代码仅发送一封邮件?

java annotations ejb schedule
1个回答
0
投票

您在这里犯了两个错误,首先应该仔细阅读有关EJB及其生命周期的教程。第一个错误是EJB@Stateless,因此它不会在计划的任务的每次运行中保留其状态。

第二个错误是在构造函数内部初始化布尔默认值。您不能信任构造函数,因为EJB引擎可能再次使用EJB距离。您必须将其初始化为以@PostConstruct

注释的方法

将bean定义为@Singleton将保留状态,并使用无论如何,这种初始化方法是一个好习惯:

@PostConstruct public void init() {

    fileNotFound = true;
}

另请参见:

Oracle's Java EE Tutorial - Enterprise Beans

© www.soinside.com 2019 - 2024. All rights reserved.