【问题标题】:Cannot autowire service into implementation of AsyncUncaughtExceptionHandler无法将服务自动装配到 AsyncUncaughtExceptionHandler 的实现中
【发布时间】:2018-08-01 11:01:48
【问题描述】:

我对弹簧自动装配有疑问。我有一个实现 AsyncUncaughtExceptionHandler 的类。

@Component
public class MyExceptionHandler implements AsyncUncaughtExceptionHandler {

    @Autowired
    MyService myService;

    @Override
    public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
        if (throwable instanceof MyException) {
            myService.handleException((MyException) throwable);
        } else {
            //...
        }
    }

当代码运行到调用 myService 的地方,会抛出 Nullpointer,因为 myService 为 null。 MyService 在其他地方自动装配没有任何问题,只有在 AsyncUncaughtExceptionHandler 的实现中自动装配似乎会导致问题。

@Service
public class MyService {

    public void handleException(MyException e) {
        //...
    }
}

我在 StackOverflow 上遇到过一些问题,解决了类似的问题。这些问题是由代理机制引起的,但我没有设法使代码工作。另外,我不确定这是否是问题。

感谢任何帮助。提前致谢。

【问题讨论】:

  • 您的MyExceptionHandler@Service@Component 还是类似的?
  • 是的,我忘了提。我已经更新了问题。
  • 添加配置MyExceptionHandler的代码。我的猜测是您使用 new MyExceptionHandler() 而不是使用 Spring 托管实例。

标签: java spring asynchronous exception autowired


【解决方案1】:

您还需要将 MyExceptionHandler 标记为 bean:

@Component
public class MyExceptionHandler implements AsyncUncaughtExceptionHandler {

【讨论】:

  • 我没有将那部分代码复制到问题中。生病更新问题。 @Component 存在于 MyExceptionHandler
【解决方案2】:

错误实际上是在我这边配置 asyncExceptionHandler。

不得不改变这个:

@Configuration
@EnableAsync
@ComponentScan
public class AsyncConfiguration implements AsyncConfigurer {

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new RccAsyncExceptionHandler();
    }
}

进入这个:

@Configuration
@EnableAsync
@ComponentScan
public class AsyncConfiguration implements AsyncConfigurer {

    @Autowired
    MyExceptionHandler rccAsyncExceptionHandler;

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return rccAsyncExceptionHandler;
    }
}

菜鸟的错误,但是找了很久都没找到。

【讨论】:

    【解决方案3】:

    这里发生的事情是,

    1. 异步代码在单独的线程上运行(因此 @ComponentScan 到 查看并初始化新线程)。
    2. 默认情况下,所有 bean 都是单例的(有关详细信息,请参阅 spring 中的 bean 范围)。由于新线程在不同的容器中运行。它不会获得服务 bean 的引用,因此为 null。
    3. 为什么@ComponentScan 没有处理它? 组件扫描主要是扫描包的子集和 服务可以在不同的包中定义。

    解决方案: 使用@ApplicationScope注解使服务bean应用范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-29
      • 2014-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-02
      • 2011-04-04
      相关资源
      最近更新 更多