Spring Boot中@Autowired注入的OkHttpClient Bean返回null该如何解决?
问题原因
- 核心原因是配置类使用了错误的注解:你当前配置类标注的
@Configurable是Spring用于给非容器管理的对象实现依赖注入的AspectJ相关注解,不会被Spring识别为配置类,因此类中定义的@Bean方法不会生效,IoC容器中根本不存在OkHttpClient类型的Bean,自然无法注入,导致实例为null。 - 次要可能原因:你调用
getProducts方法的GraphQLImpl实例是你手动new出来的,而非Spring容器注入的实例,手动创建的对象不会被Spring处理@Autowired注解,无论容器中是否存在对应Bean,注入的字段都会为null。 - 其他排查点:如果启动类的组件扫描范围没有覆盖到
HttpConfiguration、GraphQLImpl所在的包,也会导致配置类不加载、业务类不被容器管理,最终注入失败。
修复方案
- 修正配置类注解
将HttpConfiguration类上的@Configurable替换为@Configuration,让Spring识别为配置类,加载其中的Bean定义:
@Configuration // 替换原来的@Configurable public class HttpConfiguration { @Bean public OkHttpClient okHttpClient() { return new OkHttpClient(); } }
- 确保通过Spring容器获取
GraphQLImpl实例
禁止手动new GraphQLImpl(),使用@Autowired/@Resource注入该实例后再调用方法,示例如下:
// 你调用业务方法的类也要是Spring管理的Bean,比如Controller、Service等 @Service public class ProductService { // 注入实例,不要自己new @Autowired private GraphQLImpl graphQL; public void test() { // 调用方法时okHttpClient就会有值 List<Product> products = graphQL.getProducts(xx, xx, xx, xx); } }
- 检查组件扫描范围
如果你使用Spring Boot,确保启动类上的@SpringBootApplication所在的包是HttpConfiguration、GraphQLImpl的父包;如果不是,需要手动指定扫描范围:
@SpringBootApplication(scanBasePackages = {"com.xxx.你的配置类所在包", "com.xxx.你的业务类所在包"}) public class AppStart { public static void main(String[] args) { SpringApplication.run(AppStart.class, args); } }
可选优化:使用构造器注入替代字段注入,避免潜在的空指针问题,同时方便单元测试:
@Component @Slf4j public class GraphQLImpl { private final OkHttpClient okHttpClient; // Spring 4.3+之后,单构造器的情况下可以省略@Autowired public GraphQLImpl(OkHttpClient okHttpClient) { this.okHttpClient = okHttpClient; } // 后面的getProducts方法保持不变 }
内容的提问来源于stack exchange,提问作者Hola
相关产品推荐
相关产品推荐

