如何在 micronaut 2 中注入静态场?

How to inject a static field in micronaut 2?

我有一个创建对象的工厂 class。就我而言,这是 ObjectMapper (Jackson)。

@Factory
public class JacksonFactory {

  @Singleton
  public ObjectMapper getObjectMapper() {
    return new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
  }

}

我想将其注入 class:

的静态字段
public class JsonString {

  @Inject
  private static ObjectMapper mapper;

  public static String of(Object object) {
    try {
      return mapper.writeValueAsString(object);
    } catch (JsonProcessingException exception) {
      throw new RuntimeException();
    }
  }

}

但是,它不是那样工作的。每次访问映射器静态字段时,我都会得到一个 NullPointer。如果我将方法和字段设置为非静态的,一切都会很好。

我没有在文档中找到对此的解释,也许我遗漏了什么或者依赖注入有什么问题?

非常感谢您的帮助! :)

更新

好的伙计们。我不是在创建一个静态 class,而是在创建一个对象,我想将它作为依赖项注入到将要创建的所有对象中。为什么在我创建 JsonDto 对象的继承者时没有注入依赖项?

@Singleton
public class JsonString {

  @Inject
  private ObjectMapper mapper;

  public String of(Object object) {
    try {
      return mapper.writeValueAsString(this);
    } catch (JsonProcessingException exception) {
      throw new KyivAirException(exception);
    }
  }

}

我以为每次创建对象时,Micronaut都会在上下文中找到这个bin并替换它。但这似乎不是它的工作原理。 我完全糊涂了 -_\

public abstract class JsonDto {

  @Inject
  private JsonString jsonString;

  @Override
  public String toString() {
    return jsonString.of(this);
  }

}

我建议尝试类似的方法:

首先创建您的对象转换器,它将转换对象

@Singleton
public class ObjectConverter (private ObjectMapper mapper) {

  public String of(Object object) {
    try {
      return mapper.writeValueAsString(this);
    } catch (JsonProcessingException exception) {
      throw new RuntimeException(exception);
    }
  }

}

比你的 dto 更喜欢(我更喜欢构造函数注入而不是 @inject)

public abstract class MyDto(private ObjectConverter converter)  {
    
  @Override
  public String toString() {
    return converter.of(this);
  }

}

最后是您的服务,负责 dtos

@Singleton
public class MyDtoService(private ObjectConverter mapper) {

  public String get(Long id) {
  // TODO get the object from somewhere
  return mapper.of(dto)
  }

}

如果我们谈论的是来自数据库的 dto,我建议这样

interface MyJsonDbDto {
   String decode(ObjectConverter mapper) {
     return mapper.of(this)
   }
}

public class MyDbDto implements MyJsonDbDto{

}

因此服务

public class MyDbDtoService(private ObjectConverter converter, private MyDbDtoRepository repository)
      public String get(Long id) {
  // TODO get the object from repository
  return dto.decode(converter)
  }
}

希望对您有所帮助,抱歉,我主要使用 kotlin,因此我的 java 有点生疏了 ;-)

编辑:

关于您的评论,我有一个丑陋的想法,可以将其视为您重构过程的某种中间解决方案

像这样创建服务(使用上下文,因为它不像单例那样延迟加载)

@Context
public class MyDtoService {

  public static ObjectConverter mapper;

  public MyDtoService(ObjectConverter mapper) {
     MyDtoService.mapper = mapper;
  }

}

之后你可以在你的 dto 中访问它

public class MyDto {
    
  @Override
  public String toString() {
    return MyDtoService.mapper.of(this);
  }

}