我正在开发的应用程序的一个功能是每次用户获得在我们的系统中注册的发票时都会发送电子邮件。如果使用Spring框架,特别容易从Java app发送电子邮件。我使用Spring框架中的 JavaMailSenderImpl 和 SimpleMailMessage ,它可以正常工作。
但我需要在新线程中发送电子邮件,以便与SMTP服务器的通信不会减慢其余应用程序进程的速度。问题是,当我打电话
MailSender.send()
来自新线程的方法,不发送电子邮件消息,而不是在同一线程中发送时。 我尝试使用spring的 @Async注释,spring Executor和普通的旧java.lang.Thread ,但它不起作用。
可以使用spring在java中异步发送电子邮件吗?有人有类似的问题吗? 如果需要,我可以发布一些代码示例。
TNX
答案 0 :(得分:3)
它应该有用。
你需要告诉Spring它应该注意你的@Async
注释:
<task:annotation-driven />
您需要遵守一些限制:
答案 1 :(得分:3)
1)将任务名称空间添加到spring上下文中。以下xsd适用于Spring 3.0发行版。
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.0.xsd
2)在spring上下文文件中声明执行者。
<!-- Executor for the methods marked wiht @async annotations -->
<task:executor id="asyncExecutor" pool-size="25" />
3)将此配置为Spring任务
<!-- Configuration for the Runtime -->
<task:annotation-driven executor="asyncExecutor" />
这些是Spring上下文文件中所需的所有配置。
您需要使用@Async annotaion异步注释它的方法。
现在,所有使用@async注释的方法都将被异步处理为spring task executor。
答案 2 :(得分:0)
在异步线程中执行代码的一个已知问题是the exceptions thrown by that code are lost,除非you provide a specific handler to catch them。您看到的效果(即,@Async
方法无法正确执行并以某种形式的日志或堆栈跟踪的形式显示该故障的线索)通常是由这样的异常产生的,实际上是抛出但是被异步线程吞噬。
同步时@Async
方法工作的许多可能原因之一是您正在从该方法执行某些数据库操作。它在同步时有效,因为您可能是从另一个@Transactional
的{{1}}方法调用它,因此对于该线程,找到@Service
或Session
;但它在异步时不起作用,因为在这种情况下你是在一个新线程上,如果EntityManager
方法本身不是@Async
,那么就没有@Transactional
或Session
可以执行操作。
TL; DR提供一个异常处理程序来捕获异步线程将被吞并的异常,或者为了调试,使用EntityManager
/ try
大catch
的主体。 1}}方法。您可能会看到弹出一些异常,然后您需要采取适当的措施来避免它。
答案 3 :(得分:0)
您需要在Spring中启用该功能:
@EnableAsync
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}