在 Spring 框架中,注入(通常指依赖注入,Dependency Injection,简称 DI)是一种将对象所依赖的其他对象自动提供给它的机制。简单来说,就是“你需要的零件,Spring 帮你装好”。

为什么需要“注入”?

假设你写了一个 UserService 类,它需要调用 UserDao 的方法才能完成业务逻辑。传统的做法是:
 

public class UserService {
    private UserDao userDao = new UserDao();  // 自己 new 出来
}

这种方式的缺点:
高耦合:UserService 和 UserDao 的实现绑死了。
难以测试:如果想测试 UserService,你无法轻易替换成 MockDao。
配置不灵活:如果 UserDao的构造方式变了,所有 new 的地方都得改。

Spring 的“注入”怎么解决?

Spring 作为一个容器(IoC 容器),负责创建和管理对象(称为 Bean)。它会自动把依赖的对象“送”给需要它的对象,这个过程就叫注入。

你只需要告诉 Spring 哪些类是 Bean,以及它们之间的依赖关系,Spring 就会在运行时帮你装配好。

注入的常见方式

1. 字段注入(最常用)

@Service
public class UserService {
    @Autowired   // 告诉 Spring:这里需要注入一个 UserDao
    private UserDao userDao;
}


Spring 会在创建 UserService 时,自动给它赋值一个可用的 UserDao 实例。

2. 构造器注入(推荐)

@Service
public class UserService {
    private final UserDao userDao;
    @Autowired   // 如果类只有一个构造器,可以省略 @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }
}


这种方式的好处是:对象在创建时就完全初始化,且易于测试(直接 new 并传入 mock 对象)。

3. Setter 注入
 

@Service
public class UserService {
    private UserDao userDao;

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

注入的本质

把创建依赖对象的控制权从类内部转移到外部(Spring 容器),这就是控制反转(IoC) 的核心思想。你不再自己 new 对象,而是声明“我需要什么”,Spring 就会把现成的给你。

空指针异常:

Cannot invoke "resource.dao.UserDao.addUserDao()" because "this.myUserDao" is null


就是因为 myUserDao 没有被 Spring 注入(或者你手动 new 对象时忘了给它赋值)。如果使用 Spring 的 @Autowired 并正确配置,Spring 会自动注入一个非空的 UserDao 实例,就不会出现这个错误了。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐