大家好,今天我们要来聊聊 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 任何一个对象。