如何在 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);
}
}
我有一个创建对象的工厂 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);
}
}