Spring组件注入为null问题

本文深入探讨了在Spring框架中,由于使用无参构造器创建组件实例而导致的依赖注入失败问题。介绍了两种解决方法:一是利用静态变量指向Spring组件;二是避免使用无参构造器,直接通过Spring容器获取已注入依赖的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写业务的时候突然遇到一个Spring组件注入为null的问题,其实早在之前有一次就遇到过了,一直没处理,今天终于发现问题记录一下。

原先我只是为了使用建造者模式构造一个对象并调用目标方法,具体情况如下

其中的http()为静态方法,用于创建SimpleTransfer实例。如下所示

一开始并没有问题,但是后面为了封装服务调用接口及相关的参数,我又需要引入一个组件,以ConnectionBaseUtil为例

先看一下ConnectionBaseUtil

这里的ConnectionBaseUtil注册为Spring组件,同时注入了layoutUtil和restTemplate两个Spring实例,这一块是没有问题的

但是回到SimpleTransfer,我原先的注入情况如下

@Slf4j
@Data
@Component
public class SimpleTransfer extends AbstractRequestWay{
    
    @Resource
    private ConnectionBaseUtil connectionBaseUtil;

    .
    .
    .
    
}

看上去没有毛病,正常用法嘛,但其实这里忽略了一个点,那就是我们在上面使用SimpleTransfer的建造模式的时候,首先是调用的是SimpleTransfer的无参构造器创建的类实例,而我们的Spring容器中本身就存在其中两个bean,分别是SimpleTransfer和ConnectBaseUtil,同时要知道,默认情况下我们在没有指定模式时是单例模式。

也就是说,如果你这个时候new一个SimpleTransfer,此SimpleTransfer非彼SimpleTransfer,是完全不同的两个对象。后者不是通过Spring容器创建的自然就不会使用@Resource或@Autowired注入ConnectBaseUtil组件

那么这两者有什么区别呢?其实区别不大,Spring容器创建实例后(以单例模式讲),整个生命周期都由Spring管理。那么问题出在哪里。其实不管是@Resource还是@Autowired都一样,这两者都是在创建Spring组件时识别并处理的,而普通new一个实例是没有处理这些注解的,是无法注入的,其实问题基本已经解决了。

我们在上面的静态方法http()创建SimpleTransfer实例时,可以找到ConnectBaseUtil,但是并没有赋值,那么就会得到null

如何解决呢?

有两种方式:

1、以静态变量的方式将地址指向我们的组件

这样我们就可以在Spring创建SimpleTransfer组件时,将ConnectionBaseUtil注入进去并与静态成员变量绑定,即使我们使用无参构造器创建实例也无需担心使用不到我们注册的组件了。

注意这里的setConnectionBaseUtil不能为statis

2、不使用无参构造的方式自行创建实例

这种方式比较简单,直接使用注入的方式获取实例并调用方法,注意这里就不需要使用http()方法了。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值