bal*_*teo 3 spring asynchronous
我面临一个问题,因为我启用了将同步方法转换为异步方法:如果从方法体内抛出异常,我就不能再重新抛出它了.
让我先展示代码:
我的异步/任务执行器配置:
@Configuration
@EnableAsync
public class AsyncConfiguration implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(25);
taskExecutor.initialize();
return taskExecutor;
}
}
Run Code Online (Sandbox Code Playgroud)
我的异步方法:
@Async
@Override
public void sendPasswordResetInfo(String email) {
Assert.hasText(email);
Member member = memberRepository.findByEmail(email);
try {
mailerService.doMailPasswordResetInfo(member);//EXCEPTION THROWN HERE
} catch (MessagingException | MailSendException e) {
log.error("MessagingException | MailSendException", e);
// TODO: not thrown since @Async is used
throw new MailerException("MessagingException | MailSendException");//NOT CALLED
}
}
Run Code Online (Sandbox Code Playgroud)
我mailerService.doMailPasswordResetInfo引用异常时在控制台中看到的是以下堆栈跟踪:
2014-06-20 18:46:29,249 [ThreadPoolTaskExecutor-1] ERROR com.bignibou.service.preference.PreferenceServiceImpl - MessagingException | MailSendException
org.springframework.mail.MailSendException: Failed messages: javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418]
; message exception details (1) are:
Failed message 1:
javax.mail.SendFailedException: Invalid Addresses;
nested exception is:
com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418]
at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1294)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:635)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:424)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:346)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:341)
at com.bignibou.service.mailer.MailerServiceImpl.doMailPasswordResetInfo(MailerServiceImpl.java:82)
at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo_aroundBody10(PreferenceServiceImpl.java:112)
at com.bignibou.service.preference.PreferenceServiceImpl$AjcClosure11.run(PreferenceServiceImpl.java:1)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96cproceed(AbstractTransactionAspect.aj:59)
at org.springframework.transaction.aspectj.AbstractTransactionAspect$AbstractTransactionAspect$1.proceedWithInvocation(AbstractTransactionAspect.aj:65)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.aspectj.AbstractTransactionAspect.ajc$around$org_springframework_transaction_aspectj_AbstractTransactionAspect$1$2a73e96c(AbstractTransactionAspect.aj:63)
at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo_aroundBody12(PreferenceServiceImpl.java:108)
at com.bignibou.service.preference.PreferenceServiceImpl$AjcClosure13.run(PreferenceServiceImpl.java:1)
at org.springframework.scheduling.aspectj.AbstractAsyncExecutionAspect.ajc$around$org_springframework_scheduling_aspectj_AbstractAsyncExecutionAspect$1$6c004c3eproceed(AbstractAsyncExecutionAspect.aj:58)
at org.springframework.scheduling.aspectj.AbstractAsyncExecutionAspect.ajc$around$org_springframework_scheduling_aspectj_AbstractAsyncExecutionAspect$1$6c004c3e(AbstractAsyncExecutionAspect.aj:62)
at com.bignibou.service.preference.PreferenceServiceImpl.sendPasswordResetInfo(PreferenceServiceImpl.java:108)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:97)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.sun.mail.smtp.SMTPAddressFailedException: 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. OFR204_418 [418]
at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1145)
... 28 more
Run Code Online (Sandbox Code Playgroud)
仅供参考,MailerException我在应用程序中使用的是自定义异常.真正令我MailerException印象深刻的是,这个例外似乎没有被抓住也没有被重新抛出......
有人可以帮忙吗?
编辑1:我修改了我的异步服务方法如下:
@Async
@Override
public Future<Void> sendPasswordResetInfo(String email) {
Assert.hasText(email);
Member member = memberRepository.findByEmail(email);
try {
mailerService.doMailPasswordResetInfo(member);
return new AsyncResult<Void>(null);
} catch (MessagingException | MailSendException e) {
log.error("MessagingException | MailSendException", e);
//HERE: HOW DO I SEND THE MailerException USING THE FUTURE??
throw new MailerException("MessagingException | MailSendException");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不确定如何使用上面的catch块中的AsyncResult将MailerException发送到Web层 ...
Sot*_*lis 11
你的日志显示
2014-06-20 18:46:29,249 [ThreadPoolTaskExecutor-1] ERROR com.bignibou.service.preference.PreferenceServiceImpl - MessagingException | MailSendException
Run Code Online (Sandbox Code Playgroud)
记录的是
log.error("MessagingException | MailSendException", e);
Run Code Online (Sandbox Code Playgroud)
在Exception那么抛出
throw new MailerException("MessagingException | MailSendException");//NOT CALLED
Run Code Online (Sandbox Code Playgroud)
Thread由底层执行者捕获ThreadPoolTaskExecutor.此代码是异步运行的,因此在调用该方法的线程中抛出异常.
someCode();
yourProxy.sendPasswordResetInfo(someValue()); // exception thrown in other thread
moreCode();
Run Code Online (Sandbox Code Playgroud)
如果你让你的方法返回Future如此处所示,你将能够调用get()它,这将重新抛出@Async方法中抛出的任何异常,包装在一个ExecutionException.
| 归档时间: |
|
| 查看次数: |
12439 次 |
| 最近记录: |