当调用者是从外部系统接收通知的嵌入式库时,在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
被忽略。我在这里想念什么?
最佳答案
只要您不使用实际的AspectJ编译时或运行时编织,通过@Async
调用该方法(当@Transactional
用于私有(private)方法*时),this
(以及@Async
和其他类似的注释)将不起作用。
*私有(private)方法是:当方法是私有(private)时,则必须通过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?-这是相同的问题