Spring @Async被忽略了

时间:2014-03-21 14:38:34

标签: java spring

我在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会被忽略。

我在这里缺少什么?

1 个答案:

答案 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? - 这是同样的问题