@Async
在我的 Spring 应用程序中返回void
(或者Unit
,我正在用 Kotlin 编写)的方法有一点问题。
我不知道为什么,但是当@Async
方法返回时void
它只是不执行,或者至少它没有做它应该做的事情。需要说,在我的异步方法中,我想使用 发送电子邮件JavaMailSender
,所以没什么大不了的。这是方法:
@Async
override fun sendEmail(locale: Locale, subject: String, message: String, to: String) {
val msg = sender.createMimeMessage()
println("1")
val helper = MimeMessageHelper(msg, true, "utf-8")
helper.setFrom("email@example.com")
helper.setTo(to)
println("2")
helper.setSubject(getSubject(locale, null))
println("3")
helper.setText(processTemplate(locale, null, null), true)
println("4")
sender.send(msg)
println("5")
}
但是从来没有收到一封电子邮件,没有记录异常(我正在运行 testNG 测试)。
当我更改函数的签名以使其返回Future<String>
并在函数末尾添加一些虚拟返回行然后调用service.sendEmail(...).get()
时,方法的主体会神奇地执行并且电子邮件到达。
在我的@Configuration
班上,有@EnableAsync
. 我还实现AsyncConfigurer
并提供了自己的执行程序和异常处理程序,因为我认为这可能与我的执行程序 bean 定义有关,但没有任何帮助。
这让我发疯,因为我只想在后台默默地执行一些东西,但它不起作用。默默地我的意思是我不想被里面抛出的异常所困扰。
你有什么想法?
更新:
所以正如@pleft 建议的那样,我在我的方法中放了一些打印。现在,当我运行时mvn clean test
,我可以看到打印了 1,2,3,但不是每次都打印。有时只打印 1 和 2。我也把 print 放在我的 中AsyncUncaughtExceptionHandler
,但那个没有被调用。看起来后台线程被杀死得太早了。
更新 2:
我的服务配置:
@Configuration
@EnableScheduling
@EnableAsync
@ComponentScan
class ServiceConfig : ApplicationContextAware, EnvironmentAware, AsyncConfigurer {
override fun getAsyncUncaughtExceptionHandler(): AsyncUncaughtExceptionHandler {
return AsyncUncaughtExceptionHandler { ex, method, params ->
println("Exception thrown")
}
}
override fun getAsyncExecutor(): Executor {
val executor = ThreadPoolTaskExecutor()
executor.corePoolSize = 2
executor.maxPoolSize = 2
executor.setQueueCapacity(500)
executor.threadNamePrefix = "asyncThread"
executor.initialize()
return executor
}
}
/// other beans definitions..
也许它很重要,也许不重要,但我在那个processTemplate
方法中使用了 Thymeleaf。