Spring @Autowired无法向JsonDeserializer类注入ProjectConfig问题求助
问题原因及解决方案
核心原因
你的HouseTemplateDeserializer虽然标注了@Component,但Jackson可能没有使用Spring容器管理的实例,而是自行直接实例化了该类,导致Spring的依赖注入机制无法生效;另外即使Spring管理了该Bean,若Jackson调用它的时机早于ProjectConfig的初始化,也会出现注入对象为null的情况。
具体来说:
- 如果你的
HouseTemplate类上使用了@JsonDeserialize(using = HouseTemplateDeserializer.class)注解,Jackson会直接通过反射new一个实例,完全绕过Spring容器,此时@Autowired自然无效。 - Spring容器初始化Bean有顺序,若反序列化器的调用发生在
ProjectConfig初始化完成前,也会拿到null。
解决方案
方案1:让Jackson使用Spring管理的反序列化器Bean
- 移除
HouseTemplate类上的@JsonDeserialize(using = ...)注解,避免Jackson自行实例化。 - 添加Jackson配置类,将Spring管理的反序列化器注册到ObjectMapper:
@Configuration public class JacksonConfig { @Autowired private HouseTemplateDeserializer templateDeserializer; @Bean public Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() { return builder -> builder.deserializerByType(HouseTemplate.class, templateDeserializer); } }
这样Jackson就会使用Spring容器中已完成依赖注入的HouseTemplateDeserializer实例。
方案2:通过Spring上下文手动获取Bean
如果方案1不适用,可让反序列化器实现ApplicationContextAware接口,手动从Spring上下文获取ProjectConfig:
@Component public class HouseTemplateDeserializer extends JsonDeserializer<HouseTemplate> implements ApplicationContextAware { private static ApplicationContext springContext; private ProjectConfig config; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { springContext = applicationContext; } @Override public HouseTemplate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { // 延迟初始化,避免上下文未就绪的问题 if (config == null) { config = springContext.getBean(ProjectConfig.class); } logger.info("projectConfig is {}", config); // 这里编写你的反序列化逻辑 return ...; } }
注意使用静态上下文是为了适配Jackson可能复用反序列化器实例的场景。
方案3:构造函数注入+手动注册
将ProjectConfig通过构造函数注入到反序列化器,确保依赖在实例化时就已就绪:
@Component public class HouseTemplateDeserializer extends JsonDeserializer<HouseTemplate> { private final ProjectConfig config; // 构造函数注入,Spring会自动传入ProjectConfig实例 public HouseTemplateDeserializer(ProjectConfig config) { this.config = config; } @Override public HouseTemplate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { logger.info("projectConfig is {}", config); // 反序列化逻辑 return ...; } }
然后同样通过方案1中的Jackson配置类,将该反序列化器注册到ObjectMapper即可。
内容的提问来源于stack exchange,提问作者Archibald
相关产品推荐
相关产品推荐

