我在Spring中异步调用方法时遇到麻烦,因为调用程序是一个从外部系统接收通知的嵌入式库。代码如下所示:
@Service
public class DefaultNotificationProcessor implements NotificationProcessor {
private NotificationClient client;
@Override
public void process(Notification notification) {
processAsync(notification);
}
@PostConstruct
public void startClient() {
client = new NotificationClient(this, clientPort);
client.start();
}
@PreDestroy
public void stopClient() {
client.stop();
}
@Async
private void processAsync(Notification notification) {
// Heavy processing
}
}
NotificationClient
内部有一个线程,它从另一个系统接收通知。它在其构造函数中接受NotificationProcessor
,它基本上是将对通知进行实际处理的对象。
在上面的代码中,我将Spring bean作为处理器,并尝试使用@Async
注释异步处理通知。但是,似乎通知在与NotificationClient
使用的线程相同的线程中处理。实际上,@Async
会被忽略。
我在这里缺少什么?
答案 0 :(得分:28)
@Async
调用方法时, @Transactional
(以及this
和其他类似的注释)将无效(当@Async
用于私有方法时* ),只要你不使用真正的AspectJ编译时或运行时编织。
*私有方法的事情是:当方法是私有的时候,它必须通过this
调用 - 所以这就是结果然后原因
所以改变你的代码:
@Service
public class DefaultNotificationProcessor implements NotificationProcessor {
@Resource
private DefaultNotificationProcessor selfReference;
@Override
public void process(Notification notification) {
selfReference.processAsync(notification);
}
//the method must not been private
//the method must been invoked via a bean reference
@Async
void processAsync(Notification notification) {
// Heavy processing
}
}
另见以下答案:Does Spring @Transactional attribute work on a private method? - 这是同样的问题