You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Micronaut 3.9.1中带注解Bean用@Requires(missingBeans=)触发栈溢出错误

解决Micronaut中@Requires(missingBeans)配合注解处理器引发的StackOverflowError问题

问题背景

在Micronaut框架中,当Bean类被注解处理器(比如@Async、@NotNull这类会生成代理类的注解)处理时,给Bean实现类添加@Requires(missingBeans = {接口类.class})注解,会在Bean实例化阶段触发StackOverflowError。具体表现:

  • 带有@Async的ServiceOneImpl、带有@NotNull的ServiceTwoImpl注入时出现栈溢出
  • 无额外注解的ServiceThreeImpl注入完全正常
  • 移除@Requires注解后,所有Service均可正常工作

解决方案

1. 调整@Requires的判断目标为实现类

注解处理器会为接口生成代理类,此时Micronaut容器中会存在接口类型的代理Bean,导致missingBeans=ServiceOne.class的判断陷入循环:容器检查是否存在ServiceOne类型Bean→发现代理类存在→代理类依赖ServiceOneImpl→ServiceOneImpl的@Requires又检查ServiceOne是否缺失,循环往复触发栈溢出。

修改实现类的@Requires注解,将missingBeans指向实现类本身:

// ServiceOneImpl修改后
@Singleton
@Requires(missingBeans = ServiceOneImpl.class)
public class ServiceOneImpl implements ServiceOne {
    @Async
    public void doSomething() {
        // 业务逻辑
    }
}

2. 用@Primary替代接口类型的missingBeans判断

如果需求是“当没有其他同接口Bean时,当前实现类生效”,可以改用@Primary标记默认实现,其他实现类通过优先级覆盖:

@Singleton
@Primary
public class ServiceOneImpl implements ServiceOne {
    @Async
    public void doSomething() {
        // 业务逻辑
    }
}

若需要替换默认实现,给新的实现类添加更高优先级即可:

@Singleton
@Priority(1)
public class AnotherServiceOneImpl implements ServiceOne {
    // 替代实现
}

3. 改用其他条件控制Bean加载

对于需要生成代理的Bean,避免用接口作为missingBeans的判断条件,改用实现类或属性配置来控制:

@Singleton
@Requires(property = "service.one.enabled", defaultValue = "true")
public class ServiceOneImpl implements ServiceOne {
    @Async
    public void doSomething() {
        // 业务逻辑
    }
}

临时规避方法

如果暂时无法修改注解逻辑,可以:

  • 移除@Async、@NotNull这类触发代理生成的注解,改用手动实现异步逻辑、手动参数校验
  • 暂时注释掉@Requires(missingBeans)注解,待后续版本修复或调整逻辑后再恢复

内容的提问来源于stack exchange,提问作者lorda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 23:47:53