运行Spring Boot应用时遭遇异常,请求协助排查解决
异常信息
第一个异常
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:771) ~[spring-boot-2.7.12.jar:2.7.12]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:752) ~[spring-boot-2.7.12.jar:2.7.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-2.7.12.jar:2.7.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1303) ~[spring-boot-2.7.12.jar:2.7.12]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1292) ~[spring-boot-2.7.12.jar:2.7.12]
at project.art_area.ArtAreaApplication.main(ArtAreaApplication.java:19) ~[classes/:na]
第二个异常(根源)
Caused by: java.lang.NullPointerException: Cannot invoke "art_area.service.LoginServiceImpl.addCustomer(art_area.model.LoginDTO)" because "this.loginService" is null
at art_area.api.LoginApi.addCustomer1(LoginApi.java:22) ~[classes/:na]
at project.art_area.ArtAreaApplication.addCustomer(ArtAreaApplication.java:38) ~[classes/:na]
at project.art_area.ArtAreaApplication.run(ArtAreaApplication.java:26) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:768) ~[spring-boot-2.7.12.jar:2.7.12]
... 5 common frames omitted
相关代码
主类
package project.art_area; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import art_area.api.LoginApi; import art_area.model.LoginDTO; @SpringBootApplication public class ArtAreaApplication implements CommandLineRunner{ public static void main(String[] args) { SpringApplication.run(ArtAreaApplication.class, args); } @Override public void run(String... args) throws Exception { addCustomer(); } public void addCustomer() { LoginApi loginApi=new LoginApi(); LoginDTO loginDTO=new LoginDTO(); loginDTO.setFirstname("A"); loginDTO.setLastname("B"); loginDTO.setPhonenumber("1234567890"); loginDTO.setDoctorname("A"); loginDTO.setSex("M"); String s=loginApi.addCustomer1(loginDTO); System.out.println(s); } }
API类
package art_area.api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import art_area.model.LoginDTO; import art_area.service.LoginServiceImpl; @RestController @RequestMapping(value="/login") public class LoginApi { @Autowired private LoginServiceImpl loginService; @PostMapping(value = "/customer") public String addCustomer1(LoginDTO loginDTO) { if(loginService.addCustomer(loginDTO)); { return "customer Successfully added"; } //return "customer already exists"; } }
服务类
package art_area.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import art_area.model.LoginDTO; import art_area.repository.LoginRepository; import art_area.service.LoginService; @Service(value = "loginService") public class LoginServiceImpl implements LoginService{ @Autowired private LoginRepository loginRepository; @Override public boolean addCustomer(LoginDTO loginDTO) { if(loginRepository.addCustomer(loginDTO)) { return true; } return false; } }
问题原因分析
- 空指针异常根源:主类中通过
new LoginApi()手动创建实例,该对象不受Spring容器管理,@Autowired标注的loginService无法被注入,调用方法时触发空指针。 - 依赖注入不规范:LoginApi直接注入实现类
LoginServiceImpl,而非接口LoginService,违反依赖倒置原则,降低代码可维护性。 - 语法错误:LoginApi的
addCustomer1方法中,if语句后多了分号,导致后续代码块不受条件控制,无论操作结果如何都会返回成功提示。
解决方案
1. 主类注入Spring管理的LoginApi实例
修改主类,通过@Autowired获取容器中的LoginApi对象,不再手动创建:
package project.art_area; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import art_area.api.LoginApi; import art_area.model.LoginDTO; @SpringBootApplication public class ArtAreaApplication implements CommandLineRunner{ @Autowired private LoginApi loginApi; public static void main(String[] args) { SpringApplication.run(ArtAreaApplication.class, args); } @Override public void run(String... args) throws Exception { addCustomer(); } public void addCustomer() { LoginDTO loginDTO=new LoginDTO(); loginDTO.setFirstname("A"); loginDTO.setLastname("B"); loginDTO.setPhonenumber("1234567890"); loginDTO.setDoctorname("A"); loginDTO.setSex("M"); String s=loginApi.addCustomer1(loginDTO); System.out.println(s); } }
2. 修改LoginApi的依赖注入为接口类型
将LoginApi中的依赖改为接口LoginService,遵循依赖倒置原则:
package art_area.api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import art_area.model.LoginDTO; import art_area.service.LoginService; @RestController @RequestMapping(value="/login") public class LoginApi { @Autowired private LoginService loginService; @PostMapping(value = "/customer") public String addCustomer1(LoginDTO loginDTO) { if(loginService.addCustomer(loginDTO)) { return "customer Successfully added"; } return "customer already exists"; } }
3. 修复if语句的多余分号
删除if(loginService.addCustomer(loginDTO))后的分号,让条件判断生效。
验证修改
完成上述调整后,重启Spring Boot应用,CommandLineRunner会正常执行,空指针异常和启动异常将被解决,代码也更符合Spring开发规范。
内容的提问来源于stack exchange,提问作者sreenivas pothuru

