← 返回首页

第2章: IoC 容器

深入理解控制反转和Spring容器

什么是 IoC(控制反转)?

IoC(Inversion of Control,控制反转)是 Spring 框架的核心概念之一。它将对象的创建、配置和生命周期管理的控制权从应用程序代码转移到了 Spring 容器。

传统方式 vs IoC 方式

// 传统方式:程序主动创建对象 public class UserService { private UserDao userDao = new UserDaoImpl(); // 紧耦合 public void saveUser() { userDao.save(); } } // IoC 方式:容器注入对象 public class UserService { private UserDao userDao; // 松耦合 // 通过构造器或 setter 注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void saveUser() { userDao.save(); } }
💡 IoC 的核心思想:

不要主动去找依赖对象,而是让容器把依赖对象"注入"进来。这样可以降低组件之间的耦合度,提高代码的可测试性和可维护性。

BeanFactory - 基础容器

BeanFactory 是 Spring IoC 容器的基础接口,提供了完整的 IoC 服务。

BeanFactory 的特点

使用 BeanFactory

import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class BeanFactoryDemo { public static void main(String[] args) { // 加载配置文件 ClassPathResource resource = new ClassPathResource("beans.xml"); // 创建 BeanFactory BeanFactory factory = new XmlBeanFactory(resource); // 获取 Bean(此时才创建对象) HelloWorld obj = (HelloWorld) factory.getBean("helloWorld"); obj.getMessage(); } }

ApplicationContext - 高级容器

ApplicationContext 是 BeanFactory 的子接口,提供了更多企业级功能。

ApplicationContext 的特点

ApplicationContext 的实现类

// 1. ClassPathXmlApplicationContext // 从类路径加载配置文件 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 2. FileSystemXmlApplicationContext // 从文件系统加载配置文件 ApplicationContext context = new FileSystemXmlApplicationContext("c:/config/beans.xml"); // 3. AnnotationConfigApplicationContext // 基于注解的配置 ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // 4. WebApplicationContext // Web 应用专用(由 Spring MVC 自动创建)

Bean 的配置方式

1. XML 配置方式

传统的配置方式,通过 XML 文件定义 Bean:

<?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"> <!-- 定义 Bean --> <bean id="userDao" class="com.example.dao.UserDaoImpl"/> <bean id="userService" class="com.example.service.UserServiceImpl"> <!-- 注入依赖 --> <property name="userDao" ref="userDao"/> </bean> </beans>

2. 注解配置方式(推荐)

使用注解简化配置:

// 配置类 @Configuration @ComponentScan(basePackages = "com.example") public class AppConfig { // 可以在这里定义额外的 Bean } // DAO 层 @Repository public class UserDaoImpl implements UserDao { public void save() { System.out.println("保存用户"); } } // Service 层 @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; public void saveUser() { userDao.save(); } }

3. Java 配置方式

@Configuration public class AppConfig { @Bean public UserDao userDao() { return new UserDaoImpl(); } @Bean public UserService userService() { UserServiceImpl service = new UserServiceImpl(); service.setUserDao(userDao()); return service; } }

Bean 的作用域

Spring 支持多种 Bean 作用域:

作用域 说明
singleton 单例模式(默认),整个容器中只有一个实例
prototype 原型模式,每次获取都创建新实例
request 每个 HTTP 请求创建一个实例(Web 环境)
session 每个 HTTP Session 创建一个实例(Web 环境)
application 每个 ServletContext 创建一个实例(Web 环境)

指定作用域

// XML 方式 <bean id="user" class="com.example.User" scope="prototype"/> // 注解方式 @Component @Scope("prototype") public class User { // ... }

实战演示

Bean 作用域对比

点击按钮查看不同作用域的效果

📝 章节练习

练习 1:IoC 容器理解

1. ApplicationContext 和 BeanFactory 的主要区别是?




练习 2:Bean 作用域

2. Spring Bean 的默认作用域是?




本章小结

← 上一章 下一章 →