使用@Named仍触发Micronaut的NonUniqueBeanException问题求助
为什么这段代码会抛出io.micronaut.context.exceptions.NonUniqueBeanException?
问题详情
以下代码运行时抛出了NonUniqueBeanException,即便给Repository类添加了@Named注解,问题仍未解决。这是否与继承基类而非使用接口有关?
代码示例
public abstract class ObjectifyRepository<T> {} @Singleton @Named("repositoryA") public class RepositoryA extends ObjectifyRepository<EntityA> { public RepositoryA() { super(EntityA.class); } } @Singleton @Named("repositoryB") public class RepositoryB extends ObjectifyRepository<EntityB> { public RepositoryB() { super(EntityB.class); } } @Singleton public class MyService { private final RespositoryA repository; public MyService(@Named("repositoryA") RespositoryA repository) { this.repository = repository; } }
错误信息
io.micronaut.context.exceptions.NonUniqueBeanException: Multiple possible bean candidates found: [com.example.repository.$RepositoryA$Definition$Intercepted, com.example.repository.$RepositoryB$Definition$Intercepted]
问题原因与解决方案
核心问题:拼写错误
你在MyService中把RepositoryA拼写成了RespositoryA(缺少字母p)。这个拼写错误导致Micronaut无法识别你要注入的具体Bean类型,转而尝试查找其基类ObjectifyRepository的所有实现类,而RepositoryA和RepositoryB都属于该基类的实现,因此触发了“多个候选Bean”的异常。@Named注解未生效的原因
由于参数类型拼写错误,Micronaut根本没有按照你指定的RepositoryA类型去匹配Bean,而是匹配了父类ObjectifyRepository的所有实现,此时@Named("repositoryA")注解无法起到筛选作用——因为Micronaut不知道你要找的是哪个具体子类。修复方案
把MyService中的RespositoryA全部修正为正确的RepositoryA即可:@Singleton public class MyService { private final RepositoryA repository; public MyService(@Named("repositoryA") RepositoryA repository) { this.repository = repository; } }修正后,Micronaut会直接定位到唯一的
RepositoryABean,即使不加@Named注解也能正常注入(因为类型是唯一的)。关于继承基类的疑问
这个问题和“继承基类而非使用接口”完全无关。只要类型指定正确,继承基类的Bean同样可以被Micronaut正确识别和注入,不会出现此类异常。
内容的提问来源于stack exchange,提问作者Max Bachhuber
相关产品推荐
相关产品推荐

