java - Micronaut:从上下文获取 bean 的问题

标签 java dependency-injection micronaut

我有一个包含注入(inject)和强制(最终)字段的类。对于常见的情况,我可以使用 MicronautBeanFactory.getBean(type) 或 BeanContext.getBean(type) 从上下文中获取 bean,但在这种情况下我必须传递类型和参数。

我为此创建了简单的测试

@MicronautTest
public class ETLExecutorTest {

    @Inject
    private MicronautBeanFactory micronautBeanFactory;

    @Test
    void testGetBean() {
        Object[] args = new Object[] {"name", "spec", 1L};
        ObjectInstance instance = micronautBeanFactory.getBean(ObjectInstance.class, args);
    }
}

对象(bean)代码

@Prototype
public class ObjectInstance {

    @Inject
    private ObjectStorage objectStorage;

    private final String name;
    private final String spec;
    private final Long id;

    public ObjectInstance(String name, String spec, Long id) {
        this.name = name;
        this.spec = spec;
        this.id = id;
    }
}

当我运行它时,我收到异常

io.micronaut.context.exceptions.DependencyInjectionException: Failed to inject value for parameter [name] of class: com.ObjectInstance Message: Multiple possible bean candidates found: [java.lang.String, java.lang.String, java.lang.String] Path Taken: new ObjectInstance([String name],String specName,Long accountId) at io.micronaut.context.AbstractBeanDefinition.getBeanForConstructorArgument(AbstractBeanDefinition.java:1016) at com.$TableInstanceDefinition.build(Unknown Source) at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1598) at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2076) at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:1991) at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:1963) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:610) at io.micronaut.spring.context.factory.MicronautBeanFactory.getBean(MicronautBeanFactory.java:264) Caused by: io.micronaut.context.exceptions.NonUniqueBeanException: Multiple possible bean candidates found: [java.lang.String, java.lang.String, java.lang.String] at io.micronaut.context.DefaultBeanContext.findConcreteCandidate(DefaultBeanContext.java:1701) at io.micronaut.context.DefaultApplicationContext.findConcreteCandidate(DefaultApplicationContext.java:395) at io.micronaut.context.DefaultBeanContext.lastChanceResolve(DefaultBeanContext.java:2289) at io.micronaut.context.DefaultBeanContext.findConcreteCandidateNoCache(DefaultBeanContext.java:2212) at io.micronaut.context.DefaultBeanContext.lambda$findConcreteCandidate$57(DefaultBeanContext.java:2155) at io.micronaut.core.util.clhm.ConcurrentLinkedHashMap.lambda$compute$0(ConcurrentLinkedHashMap.java:721) at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) at io.micronaut.core.util.clhm.ConcurrentLinkedHashMap.compute(ConcurrentLinkedHashMap.java:733) at io.micronaut.core.util.clhm.ConcurrentLinkedHashMap.computeIfAbsent(ConcurrentLinkedHashMap.java:710) at io.micronaut.context.DefaultBeanContext.findConcreteCandidate(DefaultBeanContext.java:2154) at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:1943) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1082) at io.micronaut.context.AbstractBeanDefinition.getBeanForConstructorArgument(AbstractBeanDefinition.java:1007)

我还尝试进行另一个测试,但在这种情况下我收到没有注入(inject)字段的对象

@MicronautTest
public class ETLExecutorTest {

    @Inject
    private BeanContext beanContext;

    @Test
    void testGetBean() {
        Object[] args = new Object[] {"name", "spec", 1L};
        BeanDefinition<ObjectInstance> definition = beanContext.getBeanDefinition(ObjectInstance.class);
        ObjectInstance instance =  definition.getConstructor().invoke(args); // there are no injections here: ObjectStorage of instance = null.
    }
}

你能告诉我,我做错了什么吗???

最佳答案

micronaut尝试创建bean ObjectInstance通过构造函数但找不到 String name注入(inject),看起来这只是 ObjectInstance 的一个简单字段在这种情况下,它按预期工作:

io.micronaut.context.exceptions.DependencyInjectionException: Failed to inject value for parameter [name]

如果添加默认构造函数,则 ObjectInstance将被创建,您可以通过beanContext.getBean(ObjectInstance.class)获取bean :

@Prototype
public class ObjectInstance {

    @Inject
    private ObjectStorage objectStorage;

    private String name;
    private String spec;
    private Long id;


    public ObjectInstance() {}

    public ObjectInstance(String name, String spec, Long id) {
        this.name = name;
        this.spec = spec;
        this.id = id;
    }

}

另关注MicronautBeanFactory实现ListableBeanFactory ,这是为了与 Spring 集成

附注我建议您更改代码结构,POJO不应包含beans

关于java - Micronaut:从上下文获取 bean 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58990937/

相关文章:

c# - 如何从 C# Core 中的 DI 获取可用的 IOptions 列表?

java - 创建一个 Word (.doc) 文件,将其转换为 PDF 和 HTML,无需打开 Open Office 端口

java - 使用谷歌应用引擎上传图片的一步上传

java - 从java程序中删除硬编码文件路径

java - 如何让RestTemplate永远不抛出异常

java - 如何从curl或postman或swagger Micronaut传递值@Body MultipartBody

java - org.openqa.selenium.remote.UnreachableBrowserException : Could not start a new session. 可能原因是远程服务器地址无效

c# - 我可以在 C# 中解析带有 'GetServices(typeof(IEmpty<>))' 的开放类型泛型服务集合吗?

java - Micronaut:使用 Consul 依赖项构建 native 镜像不起作用

kotlin - 找不到 protoc-gen-grpc-kotlin-1.0.0-windows-x86_64.exe (io.grpc :protoc-gen-grpc-kotlin:1. 0.0)