当前位置: 首页 > news >正文

40岁开始学Java:控制反转IoC

在 Java 中,控制反转(Inversion of Control, IoC) 是一种设计原则,其核心思想是:将对象的创建和管理权从代码自身转移到外部容器或框架。通过 IoC,可以降低代码的耦合性,提高模块的复用性和可测试性。
在这里插入图片描述


一、IoC 的核心概念

  1. 谁控制谁?
    • 传统编程中,代码主动创建对象并管理依赖(控制权在代码手中)。
    • IoC 中,对象由外部容器(如 Spring IoC 容器)创建和管理(控制权被反转到容器)。

  2. 为什么需要 IoC?
    • 解耦对象之间的依赖关系,避免硬编码具体实现类。
    • 提高代码的可维护性和可测试性(例如通过替换依赖的模拟对象进行单元测试)。


在这里插入图片描述

二、IoC 的实现方式

1. 通过接口抽象依赖

• 定义接口,让具体实现类依赖于接口而非具体类。

public interface DataSource {
    Connection getConnection();
}

public class MySQLDataSource implements DataSource {
    @Override
    public Connection getConnection() {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/test");
    }
}

在这里插入图片描述

2. 依赖注入(DI)

• IoC 的具体实现方式通常是 依赖注入(DI),即容器负责将依赖对象注入到目标类中。
• DI 的常见方式包括:构造器注入、Setter 注入、字段注入

3. 外部容器管理对象生命周期

• 容器负责对象的创建、初始化、销毁等操作,而不是代码自己 new 对象。


在这里插入图片描述

三、Spring 框架中的 IoC 实现

1. 标记组件

• 使用 @Component(或其他 stereotype 注解,如 @Service, @Repository)标记需要被管理的类。

@Component
public class UserService {
    // 依赖注入...
}
2. 配置依赖关系

方式一:基于 XML 的配置(传统方式)
```xml


 <bean id="dataSource" class="com.example.MySQLDataSource"/>
 ```

方式二:基于 Java 配置类(推荐)
```java
@Configuration
public class AppConfig {

     @Bean
     public DataSource dataSource() {
         return new MySQLDataSource();
     }

     @Bean
     public UserService userService(DataSource dataSource) {
         return new UserService(dataSource);
     }
 }
 ```

方式三:基于注解(最简洁)
```java
@Component
public class UserService {
private final DataSource dataSource;

     @Autowired
     public UserService(DataSource dataSource) {
         this.dataSource = dataSource;
     }
 }
 ```
3. 获取容器并使用对象
public class Main {
    public static void main(String[] args) {
        // 创建 Spring 容器
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 从容器中获取对象
        UserService userService = context.getBean(UserService.class);
        userService.doSomething();
    }
}

四、IoC 的工作原理

  1. 扫描组件
    • 容器扫描所有被 @Component 或相关注解标记的类,将其注册为“bean”。

  2. 依赖解析
    • 当容器创建某个 bean 时,自动解析其依赖关系(例如构造函数参数、@Autowired 字段),并将对应依赖的 bean 注入。

  3. 生命周期管理
    • 容器控制 bean 的生命周期(如初始化、销毁),可通过 @PostConstruct@PreDestroy 注解定义回调方法。


五、IoC 的优势

  1. 解耦代码
    • 业务类不再直接依赖具体实现类,只需依赖接口。

    // 未使用 IoC 时
    public class UserService {
        private DataSource dataSource = new MySQLDataSource();
    }
    
    // 使用 IoC 后
    public class UserService {
        private final DataSource dataSource; // 由容器注入
    }
    
  2. 易于替换依赖
    • 无需修改业务代码,只需更换容器中的配置即可切换依赖实现。

    // 切换数据源只需修改配置,无需改动 UserService 类
    @Bean
    public DataSource dataSource() {
        return new PostgreSQLDataSource();
    }
    
  3. 便于单元测试
    • 通过容器注入模拟对象(Mock),隔离被测类与真实依赖。

    @Test
    void testUserService() {
        DataSource mockDataSource = Mockito.mock(DataSource.class);
        UserService userService = new UserService(mockDataSource);
        // 验证逻辑...
    }
    

六、IoC vs. DI

IoC 是一种设计思想,强调控制权的转移。
DI 是 IoC 的一种具体实现方式,通过注入依赖来实现控制反转。
Spring 框架 是 IoC 的典型实现,但 IoC 并非 Spring 独有(例如 Guice、PicoContainer 等框架也支持)。


七、总结

通过 IoC 和 Spring 框架,可以实现以下目标:

  1. 集中管理对象:所有对象的创建和依赖由容器统一控制。
  2. 减少重复代码:避免手动编写对象创建和依赖注入逻辑。
  3. 提高可维护性:修改依赖时无需改动业务代码。
  4. 支持 AOP、事务管理等高级功能:基于 IoC 的扩展能力。

如果希望深入理解,可以尝试在 Spring Boot 项目中实践上述示例,并观察容器如何自动管理对象的生命周期。

相关文章:

  • 前端知识点---路由模式-实例模式和单例模式(ts)
  • 【redis】全局命令set、get、keys
  • 【linux网络编程】浏览网页时客户端与服务器之间数据交互的完整过程
  • 根据输入汉字生成带拼音的米字格字帖
  • 对接RAGflow的API接口报错
  • Java本地缓存简单实现,支持SpEL表达式及主动、过期、定时删除
  • 解锁日常养生密码,拥抱健康生活
  • RabbitMQ学习笔记
  • 腾讯云大模型知识引擎LKE+DeepSeek结合工作流升级智能客服
  • Python模块的版本管理与文档编写
  • 初学者对爬虫的实例(抖音/b站)python篇
  • 实现一键不同环境迁移ES模板
  • 在IDEA中进行git回滚操作:Reset current branch to here‌或Reset HEAD
  • pyqt联合designer的运用和设置
  • 2025年全球生成式AI消费应用发展趋势报告
  • Lucas定理介绍及证明
  • 深入理解 Java 中的 CopyOnWrite 机制
  • 解决电脑问题(1)——硬件问题
  • manus本地部署使用体验
  • 「DataX」数据迁移-IDEA运行DataX方法总结
  • pdf怎么做电子书下载网站/by72777最新域名查询
  • 如何制作网站网页/网络推广方式有哪些
  • 开发者模式一直开着有危害吗/长沙网站seo
  • 国外做文化的网站/专业黑帽seo推广
  • 母版页做网站例子/电话百度
  • 涟水做网站/seo日常优化内容是什么