SpringBoot使用@Autowired注入Service调用方法报空指针异常怎么解决
问题根因
你遇到的空指针是Spring依赖注入的执行顺序和Java类初始化顺序不匹配导致的:
Java创建类实例时,会先执行成员变量的赋值操作,再执行构造方法;而Spring的@Autowired字段注入是在类实例化完成之后,通过反射给对应字段赋值的。你旧版代码中直接在成员变量位置执行ArrayList<Product> products = productService.getAllProduct();,此时productService还没有被Spring注入,还是默认的null值,调用方法自然触发NullPointerException。
可行解决方案
构造注入(你已经采用的方案,是Spring官方推荐的注入方式)
构造注入会让Spring先完成依赖的ProductService实例的创建,再将实例传入Controller的构造方法,此时在构造方法内调用productService的方法是完全安全的,配合final修饰成员变量还能保证引用不可变,代码健壮性更高。Spring 4.3及以上版本如果类只有一个构造方法,甚至可以省略构造方法上的@Autowired注解。用
@PostConstruct注解实现初始化
如果你习惯用字段注入,可以把products的初始化逻辑放到标注了@PostConstruct的方法中,该注解标注的方法会在Spring完成所有依赖注入后自动执行,不会出现空指针问题,示例代码如下:
@Controller public class MainController { @Autowired private ProductService productService; private ArrayList<Product> products; @PostConstruct public void initProducts() { products = productService.getAllProduct(); } // 其余方法不变 }
- 接口内按需调用
如果你的商品列表不需要在Controller启动时就预加载,完全可以在请求接口内实时调用Service方法获取数据,既能避免空指针,还能拿到Service中最新的商品列表数据,示例代码如下:
@GetMapping("/products") public String product(Model model){ model.addAttribute("products", productService.getAllProduct()); return "product"; }
内容的提问来源于stack exchange,提问作者Veritas1832
相关产品推荐
相关产品推荐

