在Service中使用JpaRepository时出现NPE(空指针异常)求助
问题分析与解决方案
核心问题原因
- 手动实例化Service导致依赖失效:你在Controller中通过
new Service(this.repository)手动创建Service对象,这个对象不在Spring容器的管理范围内。Spring只会对自身创建并管理的Bean执行依赖注入,所以即便Service类标注了@Service和@AllArgsConstructor,这个手动new出来的Service里的repository也不会被Spring注入。 - 字段注入时机冲突:
@Autowired的字段注入是在Controller对象构造完成后才执行的。而你在Controller的成员变量位置直接初始化Service,此时repository还没被Spring注入,处于null状态,传给Service后自然会导致调用repository.save()时抛出空指针异常。
修复方案
方案1:在Controller中注入Spring管理的Service实例
直接通过构造注入(推荐)或字段注入的方式获取Spring容器中的Service Bean,不要手动new:
@RestController public class Controller { // Spring 4.3+支持无@Autowired的构造注入,更利于依赖校验和单元测试 private final Service service; public Controller(Service service) { this.service = service; } @PostMapping(value = "/") public void add(@RequestBody Entity entity) { service.add(entity); } }
如果习惯字段注入,也可以这样写:
@RestController public class Controller { @Autowired private Service service; @PostMapping(value = "/") public void add(@RequestBody Entity entity) { service.add(entity); } }
方案2:保持Service的Spring管理机制
你的Service类写法是正确的(@Service + @AllArgsConstructor),Spring会自动通过构造方法为它注入Repository实例。只要不手动new Service,而是从Spring容器中获取实例,依赖就能正常注入。
额外说明
- 禁止在Spring组件中手动new其他Spring管理的Bean,这会破坏Spring的依赖注入机制,导致依赖失效。
- 构造注入是Spring官方推荐的注入方式,能确保依赖在对象创建时就完成初始化,从根源避免空指针问题,同时也更便于单元测试。
内容的提问来源于stack exchange,提问作者Bejenariu Ionut
相关产品推荐
相关产品推荐

