Spring独立Java库中ObjectMapper依赖注入空指针问题
问题根源
你直接通过new ConfigurationProcessor()创建对象,这个对象不在Spring容器的管理范围内,Spring的依赖注入机制只对容器中初始化的Bean生效,所以objectMapper会是null,触发空指针异常。
解决方案
根据你的客户端是否为Spring应用,分两种处理方式:
场景1:客户端是Spring应用(如Spring Boot)
1. 调整库中的配置类
去掉ModuleProvider上的@Component(@Configuration本身就是Spring组件,无需重复标注):
package com.my.package.search.modules; @Configuration public class ModuleProvider { @Bean public ObjectMapper getObjectMapper() { return new ObjectMapper().enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); } }
2. 调整ConfigurationProcessor
去掉@ComponentScan(让客户端负责扫描包或导入配置,避免库内部重复扫描),同时把objectMapper改为private final(配合@RequiredArgsConstructor更规范):
@Slf4j @Component @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class ConfigurationProcessor { private final ObjectMapper objectMapper; @SneakyThrows public void processTheme(String name) { String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }"; Car car = objectMapper.readValue(json, Car.class); System.out.println("all gg" + car); } }
3. 客户端使用方式
客户端需要在自己的Spring配置中,通过以下方式之一引入你的库组件:
- 在启动类或配置类上添加
@ComponentScan(basePackages = {"com.my.package.search"}) - 或者用
@Import(ModuleProvider.class)直接导入你的配置类
之后客户端必须从Spring容器获取ConfigurationProcessor实例,比如:
// 客户端代码示例 @Service public class SomeCaller { private final ConfigurationProcessor configurationProcessor; // 通过构造注入获取容器内的Bean public SomeCaller(ConfigurationProcessor configurationProcessor) { this.configurationProcessor = configurationProcessor; } public void doCall() { configurationProcessor.processTheme("test"); } }
绝对不能用new ConfigurationProcessor()手动创建对象。
场景2:客户端非Spring应用
如果客户端不使用Spring,你需要手动实现简单的工厂模式,避免依赖Spring容器:
public class LibraryFactory { // 提前初始化ObjectMapper和ConfigurationProcessor private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() .enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); private static final ConfigurationProcessor CONFIG_PROCESSOR = new ConfigurationProcessor(OBJECT_MAPPER); // 提供获取实例的方法 public static ConfigurationProcessor getConfigurationProcessor() { return CONFIG_PROCESSOR; } }
客户端调用时直接通过工厂获取实例:
// 客户端代码示例 public class SomeCaller { public void doCall() { ConfigurationProcessor processor = LibraryFactory.getConfigurationProcessor(); processor.processTheme("test"); } }
额外注意事项
- 使用
@RequiredArgsConstructor时,建议把依赖变量声明为private final,既保证不可变性,也能让Lombok正确生成构造方法。 - Spring环境下,所有需要依赖注入的对象都必须由Spring容器管理,手动new的对象无法享受DI特性。
内容的提问来源于stack exchange,提问作者Jeya Kumar
相关产品推荐
相关产品推荐

