@Autowired搭配@SpringBootApplication失效,求助解决空指针问题
Spring Boot @Autowired空指针异常解决方案
问题背景
切换到@SpringBootApplication后,@Autowired注解无法正常工作,运行时抛出空指针异常。相关代码及异常信息如下:
主类代码
package com.example; import com.example.domain.Print; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DbApplication { public static void main(String[] args) { SpringApplication.run(DbApplication.class, args); Print print = new Print(); print.testSayHello(); } }
Test类代码
package com.example.domain; import org.springframework.stereotype.Component; @Component public class Test { public void sayHello(){ System.out.println("Hello"); } }
Print类代码
package com.example.domain; import org.springframework.beans.factory.annotation.Autowired; public class Print { @Autowired public Test test; public void testSayHello(){ test.sayHello(); } }
异常信息
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.example.domain.Test.sayHello()" because "this.test" is null at com.example.domain.Print.testSayHello(Print.java:11) at com.example.DbApplication.main(DbApplication.java:14)
问题原因
- Print类未被Spring容器托管:直接通过
new Print()创建的对象不属于Spring IoC容器,Spring无法为其注入依赖。 - @Autowired仅对Spring管理的Bean生效:只有由Spring创建和管理的对象,Spring才会自动完成
@Autowired的依赖注入操作。
解决方法
方法1:将Print类声明为Spring组件
- 给
Print类添加@Component注解,让Spring自动扫描并管理该类:
package com.example.domain; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class Print { @Autowired private Test test; // 建议使用private修饰,保证封装性 public void testSayHello(){ test.sayHello(); } }
- 修改主类,从Spring容器中获取
Print实例,而非手动创建:
package com.example; import com.example.domain.Print; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; @SpringBootApplication public class DbApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(DbApplication.class, args); Print print = context.getBean(Print.class); // 从容器获取Bean实例 print.testSayHello(); } }
方法2:使用构造方法注入(官方推荐)
构造方法注入能避免空指针,同时保证依赖不可变,是Spring官方推荐的注入方式:
- 修改
Print类,改用构造方法注入依赖:
package com.example.domain; import org.springframework.stereotype.Component; @Component public class Print { private final Test test; // Spring会自动传入Test实例 public Print(Test test) { this.test = test; } public void testSayHello(){ test.sayHello(); } }
- 主类代码同方法1,从Spring容器中获取
Print实例即可。
补充说明
之前使用常规配置时功能正常,是因为你可能手动在配置类中声明了Print的Bean,并通过上下文获取实例。而@SpringBootApplication包含@ComponentScan注解,默认扫描主类所在包及其子包下的组件类,只要给Print添加@Component,Spring就能自动扫描并管理它。
内容的提问来源于stack exchange,提问作者overloewner
相关产品推荐
相关产品推荐

