所以我有一个相对简单的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)。我在做错什么,以及如何使此代码仅发送一封邮件?
您在这里犯了两个错误,首先应该仔细阅读有关EJB及其生命周期的教程。第一个错误是EJB
为@Stateless
,因此它不会在计划的任务的每次运行中保留其状态。
第二个错误是在构造函数内部初始化布尔默认值。您不能信任构造函数,因为EJB引擎可能再次使用EJB距离。您必须将其初始化为以@PostConstruct
将bean定义为@Singleton
将保留状态,并使用无论如何,这种初始化方法是一个好习惯:
@PostConstruct public void init() {
fileNotFound = true;
}
另请参见: