无法在 Micronaut 中注入具有命名限定符的不同 bean

Could not inject different beans with named qualifier in Micronaut

我定义了一个 ObjectMapper 工厂 class 是这样的:

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

import io.micronaut.context.annotation.Factory;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

@Factory
public class MyObjectMapper {

    @Singleton
    @Named("jsonObjectMapper")
    public ObjectMapper getJsonObjectMapper() {
        return new ObjectMapper(new JsonFactory());
    }

    @Singleton
    @Named("yamlObjectMapper")
    public ObjectMapper getYamlObjectMapper() {
        return new ObjectMapper(new YAMLFactory());
    }

}

然后,在客户端 class 上,我尝试像这样注入它们:

import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

@Singleton
public class MyServiceImpl implements MyService {

    private ObjectMapper jsonMapper;

    private ObjectMapper yamlMapper;

    @Inject
    @Named("jsonObjectMapper")
    public void setJsonMapper(ObjectMapper jsonMapper) {
        this.jsonMapper = jsonMapper;
    }

    @Inject
    @Named("yamlObjectMapper")
    public void setYamlMapper(ObjectMapper yamlMapper) {
        this.yamlMapper = yamlMapper;
    }
...

我的目标是让 jsonMapper 通过 @Named("jsonObjectMapper")MyObjectMapper class 和 yamlMapper 上通过 @Named("yamlObjectMapper") 注入].但是,当我尝试调试时,jsonMapperyamlMapper 具有相同的引用,这意味着它们是由相同的 ObjectMapper 注入的。我的问题是如何在 Micronaut 上为 json 和 yaml 映射器注入 2 个不同的 bean?

谢谢!

注入 qualified by name 可以通过方法参数上使用的 @Named 注释来完成,而不是方法本身。这意味着在您的情况下,您必须将 @Named 注释移动到 setJsonMappersetYamlMapper 方法参数。

@Singleton
public class MyServiceImpl {

    private ObjectMapper jsonMapper;

    private ObjectMapper yamlMapper;

    @Inject
    public void setJsonMapper(@Named("jsonObjectMapper") ObjectMapper jsonMapper) {
        this.jsonMapper = jsonMapper;
    }

    @Inject
    public void setYamlMapper(@Named("yamlObjectMapper") ObjectMapper yamlMapper) {
        this.yamlMapper = yamlMapper;
    }

    // ...
}

或者,您可以将构造注入与每个参数的 @Named 注释结合使用。它允许您将这两个字段标记为私有,只是为了确保这些对象不会在运行时重新分配。

@Singleton
public class MyServiceImpl {

    private final ObjectMapper jsonMapper;

    private final ObjectMapper yamlMapper;

    public MyServiceImpl(
            @Named("jsonObjectMapper") ObjectMapper jsonMapper,
            @Named("yamlObjectMapper") ObjectMapper yamlMapper) {
        this.jsonMapper = jsonMapper;
        this.yamlMapper = yamlMapper;
    }

    // ...
}