Java应用中使用Guice注入ObjectMapper实例失败问题排查
问题分析与解决方案
核心原因
是的,你在getObjectMapper方法中手动new BlockDeserializer()的操作,正是导致注入的ObjectMapper为null的原因。
DI容器只会对自身创建并管理的实例执行依赖注入逻辑。你直接通过new关键字创建的BlockDeserializer实例不在容器的管理范围内,因此构造函数上的@Inject注解不会被容器处理,objectMapper字段自然无法被注入值,最终为null。
解决方案
要解决这个问题,需要让BlockDeserializer由DI容器管理,并避免循环依赖问题(因为ObjectMapper依赖BlockDeserializer,而BlockDeserializer又依赖ObjectMapper),具体步骤如下:
1. 修改JacksonModule,从容器注入BlockDeserializer
将getObjectMapper改为非静态方法,让容器注入BlockDeserializer实例,而非手动创建:
public class JacksonModule extends AbstractModule { @Provides @Singleton @Named("dynamicWidgetDeserializer") public ObjectMapper getObjectMapper(BlockDeserializer blockDeserializer) { SimpleModule simpleModule = new SimpleModule(); simpleModule.addDeserializer(Block.class, blockDeserializer); ObjectMapper objectMapper = new ObjectMapper() .registerModule(simpleModule); return objectMapper; } }
2. 调整BlockDeserializer的依赖注入方式,避免循环依赖
使用Provider<ObjectMapper>延迟获取实例,解决ObjectMapper与BlockDeserializer的循环依赖问题:
public class BlockDeserializer extends StdDeserializer<Block> { private final Provider<ObjectMapper> objectMapperProvider; @Inject public BlockDeserializer(@Named("dynamicWidgetDeserializer") Provider<ObjectMapper> objectMapperProvider) { super(Block.class); this.objectMapperProvider = objectMapperProvider; } @Override public Block deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { // 实际使用时再获取ObjectMapper实例 ObjectMapper objectMapper = objectMapperProvider.get(); // 你的反序列化逻辑 } }
3. 移除无用的无参构造
可以删除BlockDeserializer中的无参构造函数,因为DI容器会使用带@Inject注解的构造函数创建实例:
// 移除这个无参构造 // public BlockDeserializer() { // this(null); // }
说明
通过上述调整,BlockDeserializer由DI容器管理,其依赖的ObjectMapper会通过Provider延迟注入,既解决了null问题,也避免了循环依赖导致的初始化失败。
内容的提问来源于stack exchange,提问作者ASHOK KUMAR
相关产品推荐
相关产品推荐

