双面
发布于 2025-07-09 / 93 阅读
0
0

基于 XML 的控制反转(IoC)和依赖注入(DI)讲解

大家好,今天我们要来聊聊 Spring 框架中的两个非常重要的概念:控制反转(Inversion of Control,简称 IoC)依赖注入(Dependency Injection,简称 DI)

这篇文章我们主要讲的是通过 XML 配置文件 来实现 IoC 和 DI,适合刚入门的小白朋友学习使用 Spring 的基本思想。

一、准备环境

首先我们需要引入一些 Maven 依赖,确保我们的项目能正常运行 Spring 框架。

<!-- JUnit 测试用 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.1</version>
    <scope>test</scope>
</dependency>

<!-- Spring 核心依赖 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.2.7</version>
</dependency>

二、创建 Spring 的配置文件

resources 目录下新建一个 XML 文件,比如我们就叫它 spring.xml。这个文件就是我们整个 Spring 容器的核心配置。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 后面的内容都写在这里 -->

</beans>

三、创建两个简单的类

接下来我们分别创建两个类:

  • UserService 类(位于包 org.service 下)

  • UserDao 类(位于包 org.dao 下)

这两个类都有一个方法叫做 demo(),作用就是在控制台输出一句话,表示这个方法被调用了。比如:

UserService demo方法被调用
UserDao demo方法被调用

这里为了简单起见,我们不使用接口,直接通过类与类之间的调用来演示。

四、手动 new 对象?太老土了!

以前我们想用某个对象,都是自己写代码 new 出来的,比如这样:

UserService service = new UserService();

但 Spring 的核心思想是:把对象的创建交给框架来做,也就是所谓的 控制反转。我们不需要自己 new,而是让 Spring 帮我们管理这些对象。

在 XML 中注册 Bean

怎么告诉 Spring 要帮我们管理哪些对象呢?很简单,在 spring.xml 中添加 <bean> 标签。

<bean name="Service" class="org.service.UserService"/>
<bean name="Dao" class="org.dao.UserDao"/>

上面这段代码的意思是:

  • 给 Spring 注册了一个名字为 Service 的对象,它是 org.service.UserService 这个类的实例。

  • 另外还有一个名字为 Dao 的对象,是 org.dao.UserDao 的实例。

五、实现类之间的调用(依赖注入)

现在问题来了:如果我们想在 UserService 中调用 UserDao 的方法,该怎么办?

在传统的做法中,我们会这样做:

public class UserService {
    private UserDao userDao = new UserDao();

    public void demo() {
        userDao.demo();
    }
}

但是这样写的话,又回到了“自己 new 对象”的老路子,不符合 Spring 的思想。

那怎么办?我们可以让 Spring 自动帮我们把 UserDao 注入到 UserService 中去!

步骤如下:

1. 修改 spring.xml 文件:

<bean class="org.service.UserService">
    <property name="userDao" ref="Dao"/>
</bean>
<bean name="Dao" class="org.dao.UserDao"/>

这段代码的意思是:

  • 创建一个 UserService 的 bean,并且给它的 userDao 属性注入一个引用为 Dao 的对象。

  • ref="Dao" 表示要注入的对象已经在前面定义好了,名字叫 Dao。

2. 修改 UserService.java

为了让 Spring 能顺利注入 UserDao,我们需要提供一个 setter 方法:

public class UserService {
    // 由 Spring 注入的 UserDao 实例
    private UserDao userDao;

    // 示例方法,展示如何使用注入进来的 userDao
    public void demo() {
        System.out.println("UserService demo方法被调用");
        userDao.demo(); // 使用注入进来的对象
    }

    // 提供 setter 方法,用于 Spring 注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

六、测试一下吧!

写个测试类跑一下看看效果是不是符合预期。

@Test
public void demoTest() {
    // 加载 Spring 配置文件,启动 IoC 容器
    ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("spring.xml");

    // 从容器中获取 UserService 实例
    UserService userService = ioc.getBean(UserService.class);

    // 调用方法,看看是否成功注入了 UserDao
    userService.demo();
}

如果一切顺利,控制台应该会输出:

UserService demo方法被调用
UserDao demo方法被调用

这说明我们成功地通过 Spring 的控制反转和依赖注入实现了类之间的调用!


小结:

  • 控制反转(IoC):对象的创建不再由程序员手动完成,而是交给 Spring 容器来管理。

  • 依赖注入(DI):Spring 容器会自动帮我们把需要的对象注入到指定的位置。

  • 我们通过 XML 配置文件 来定义哪些类需要被管理,以及它们之间怎么互相注入。

  • 最后我们通过一个简单的例子,实现了 UserService 调用 UserDao 的功能,而没有自己 new 任何一个对象。


评论