3

@AsyncSpring アプリで返す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>、ダミーの return 行を関数の最後に追加してから を呼び出す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 を使用しています。

4

1 に答える 1