【问题标题】:Spring @Async ignoredSpring @Async 被忽略
【发布时间】:2014-04-28 23:57:40
【问题描述】:

当调用者是从外部系统接收通知的嵌入式库时,我在 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 被忽略了。

我在这里缺少什么?

【问题讨论】:

  • 代理不适用于内部呼叫。对异步方法的调用需要来自对代理的引用,而不是对实际对象的引用。

标签: java spring


【解决方案1】:

@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? -- 这是同一个问题

【讨论】:

  • 是否可以在 DefaultNotificationProcessor 中自动装配 DefaultNotificationProcessor?或者也许可以在注释为服务的类上执行此操作,因为当我使用组件注释时它不起作用。
  • @MarcinErbel 看看:stackoverflow.com/questions/5152686/self-injection-with-spring/… --- 抽象使用 Spring 4.3 或使用 @Resource 而不是 @Autowired
  • 如果使用@Autowired,你还需要@Lazy,否则你会创建一个依赖循环。
  • @Ralph为什么我们这里需要process方法,即使只有一个通知也不能processAsync照顾?
猜你喜欢
  • 2018-06-24
  • 2020-05-07
  • 2018-07-26
  • 1970-01-01
  • 2020-03-12
  • 1970-01-01
  • 2012-05-19
  • 2015-08-03
  • 2021-08-26
相关资源
最近更新 更多