簡體   English   中英

使 EJB @Schedule 中的方法只被調用一次

[英]Make a method inside EJB @Schedule to be called only once

所以我有一個比較簡單的EJB。 我想每十秒鍾檢查一次 pdf 文件在特定位置,當我找到它時發送郵件。 工作正常,正如預期的那樣,但我總是收到兩個相同的 email 而不是一個。代碼是這樣的:

@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){
            GlassfishLogger.log("Inside processSendMail. The fileNotFound variable is " + 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) 在這里建議)。 我做錯了什么以及如何使此代碼僅發送一封郵件?

更新

我在processSendMail方法中添加了一個日志,結果如下:

在此處輸入圖像描述


在此處輸入圖像描述

您在這里犯了 2 個錯誤,您應該首先仔細閱讀有關 EJB 及其生命周期的教程。 第一個錯誤是EJB@Stateless ,因此它不會在每次運行計划任務時保留其狀態。

第二個錯誤是在構造函數中初始化 boolean 默認值。 您不能信任構造函數,因為容器可能會再次使用 EJB 實例。 您必須將其初始化為使用@PostConstruct注釋的方法

將 bean 定義為@Singleton將保留狀態,並且無論如何使用以下初始化方法是一個好習慣:

@PostConstruct 
public void init() {

    fileNotFound = true;
}

也可以看看:

Oracle的Java EE教程-企業Beans

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM