对@Async方法使用以下配置:
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
//Just to experiment
return new SimpleAsyncTaskExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
}
有没有办法“获得”自动装配(或类似)服务的能力?
我想使用此类服务记录数据库中的错误并使用常用服务。
非工作样本:
@Component //seems pointless
public class CustomAsyncExceptionHandler extends ServiceCommons implements AsyncUncaughtExceptionHandler {
protected Logger LOG = LoggerFactory.getLogger(this.getClass());
@Autowired
private MyService myService; //always null
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
//null pointer !
myService.doSomething(throwable);
}
}
在@Async方法中不使用时,@ ControllerAdvice全局异常处理程序允许@Autowired字段。在这种情况下为什么不呢?这是因为异步线程管理吗?
答案 0 :(得分:1)
我刚刚遇到了这个问题并以这种方式解决了:
@Configuration
@EnableAsync
public class MyAsyncConfigurer implements AsyncConfigurer {
private CustomAsyncExceptionHandler customAsyncExceptionHandler;
//...
//other code here
//...
@Autowired
public void setCustomAsyncExceptionHandler(CustomAsyncExceptionHandler customAsyncExceptionHandler) {
this.customAsyncExceptionHandler = customAsyncExceptionHandler;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return this.customAsyncExceptionHandler;
}
}
使用@Component 注释的自定义异步异常处理程序:
@Component
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
private MyMailService myMailService;
@Autowired
public void setMyMailService(MyMailService myMailService) {
this.myMailService= myMailService;
}
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
myMailService.sendMailToAdmin(throwable, method.getName());
}
}
IoC 正确地注入了 myMailService 和 customAsyncExceptionHandler,没有错误。
答案 1 :(得分:0)
我不认为我的解决方案是最优雅的,但请告诉我你的想法。我们的想法是通过使用ApplicationContextAware接口绕过自动注入机制。我的第一次尝试是让我的AsyncUncaughtExceptionHandler实现类也实现ACAware。但那没用。不知何故,这个类,甚至注释为组件或服务似乎都在Spring环境之外。所以我这样做了:
@Configuration
@EnableAsync
public class DemoAsyncConfigurer implements AsyncConfigurer, ApplicationContextAware {
private ApplicationContext applicationContext;
在同一个班级:
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
DemoAsyncExceptionHandler demoHandler = new DemoAsyncExceptionHandler(); // you can't add the parameter in this constructor, for some reason...
demoHandler.setApplicationContext(applicationContext);
return demoHandler;
}
/**
*
* {@inheritDoc}
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
我的DemoAsyncExceptionHandler具有以下内容:
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void handleUncaughtException(Throwable throwable, Method method, Object... params) {
UserService userService = this.applicationContext.getBean("userService", UserService.class);
// call userService method
那很有效!希望我帮助