当调用者是从外部系统接收通知的嵌入式库时,在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?-这是相同的问题

10-02 04:18
查看更多