Spring核心之IOC与DI:手写工厂到Spring容器演进(第一部分)

IOC容器与DI注入 Spring Core 学习 IOC容器与DI深入理解 阅读详情

一、Spring框架简介

Spring是一个轻量级的、开源的JavaEE全栈式应用框架。它的核心价值在于简化企业级应用开发,通过提供一系列模块化解决方案,让开发者能够更专注于业务逻辑。

Spring的核心优势:

  1. IOC(控制反转):将对象的创建、管理与依赖关系的控制权从程序代码“反转”到Spring容器,实现解耦。

  2. AOP(面向切面编程):允许将遍布应用的公共行为(如日志、事务)从核心业务逻辑中分离,增强模块化。

  3. 粘合剂:它就像一个“框架的框架”,能够非常方便地整合MyBatis、Hibernate、Struts等其他优秀的第三方技术与框架。

二、IOC(控制反转):从工厂模式到Spring容器

2.1 问题起源:耦合

在传统编码中,对象间的依赖关系通常是“硬编码”的。例如,在Service层中直接new一个Dao层的实现类。这种强耦合导致代码僵化,一旦需要更换实现,就必须修改源代码。

2.2 IOC思想

  • 正转:程序员在代码中主动new对象,控制权在程序员手中。

  • 反转(IOC):对象的创建不再由程序员控制,而是交给一个“工厂”或“容器”来负责。程序员从主动创建变为被动接收对象。

核心:控制对象的创建权发生反转。

2.3 手工实现IOC:工厂模式

在接触Spring前,我们可以用“工厂+反射+配置文件”模拟IOC思想,解耦Service和Dao。

实现步骤:

  1. 定义配置文件​ (bean.properties):将类名以键值对形式存储。

    userDao=com.hg.dao.UserDaoImpl
    userService=com.hg.service.UserServiceImpl
  2. 创建工厂类:在静态代码块中读取配置文件。

  3. 反射创建对象:通过Class.forName(className).newInstance()创建对象实例,并存入一个Map容器。

  4. 提供获取方法:对外提供getBean(String id)方法,从Map中返回所需对象。

此时,Service中不再出现new UserDaoImpl()的代码,而是从工厂获取,初步实现解耦。

2.4 Spring的IOC容器

Spring将上述工厂模式的思想发挥到极致,提供了一个功能强大的IOC容器。

Spring IOC 入门步骤:

  1. 引入依赖​ (pom.xml)

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.3.23</version> <!-- 请使用合适版本 -->
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.36</version>
    </dependency>
  2. 准备日志配置​ (log4j.properties)

  3. 编写Spring配置文件​ (applicationContext.xml)

    <?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标签:将一个类的对象交给Spring IOC容器管理 -->
        <!-- id: 对象在容器中的唯一标识 (Map的key) -->
        <!-- class: 对象的全限定类名 -->
        <bean id="userDao" class="com.hg.dao.UserDaoImpl"></bean>
        <bean id="userService" class="com.hg.service.UserServiceImpl"></bean>
    </beans>
  4. 从容器中获取Bean

    public class Test {
        public static void main(String[] args) {
            // 1. 加载Spring配置文件,初始化IOC容器
            ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 2. 从容器中获取Bean对象
            UserService userService = ac.getBean("userService", UserService.class);
            // 3. 使用对象
            userService.saveUser();
        }
    }

三、DI(依赖注入)

IOC解决了对象创建的问题。DI(依赖注入)​ 则专门解决对象间的依赖关系赋值问题,它是IOC思想的具体实现。

3.1 构造方法注入

通过类的构造方法来完成依赖的注入。

  1. 目标类提供带参构造方法

    public class UserServiceImpl implements UserService {
        private UserDao userDao;
        private String msg;
        // 构造方法
        public UserServiceImpl(UserDao userDao, String msg) {
            this.userDao = userDao;
            this.msg = msg;
        }
    }
  2. 在配置文件中使用<constructor-arg>标签注入

    <bean id="userService" class="com.hg.service.UserServiceImpl">
        <!-- name: 通过构造方法参数名匹配 -->
        <constructor-arg name="userDao" ref="userDao"/>
        <!-- index: 通过构造方法参数索引位置匹配 (从0开始) -->
        <constructor-arg index="1" value="示例文本"/>
    </bean>
    <bean id="userDao" class="com.hg.dao.UserDaoImpl"/>
    • ref:引用IOC容器中其他Bean的id。

    • value:注入基本数据类型或String类型的值。

3.2 Setter方法注入(最常用)

通过类的Setter方法来完成依赖注入。

  1. 目标类提供Setter方法

    public class UserServiceImpl implements UserService {
        private UserDao userDao;
        private String msg;
        // Setter 方法
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
  2. 在配置文件中使用<property>标签注入

    <bean id="userService" class="com.hg.service.UserServiceImpl">
        <!-- name: 取set方法名去掉“set”后首字母小写的部分,例如setUserDao -> userDao -->
        <property name="userDao" ref="userDao"/>
        <property name="msg" value="示例文本"/>
    </bean>
    <bean id="userDao" class="com.hg.dao.UserDaoImpl"/>

3.3 自动注入(Autowire)

让Spring容器自动寻找匹配的Bean并完成注入,无需在<property>或<constructor-arg>中显式配置。

byType方式:根据属性的类型,在IOC容器中查找匹配的Bean。要求容器中同类型的Bean必须唯一。

<bean id="userService" class="com.hg.service.UserServiceImpl" autowire="byType"/>
<bean id="userDao" class="com.hg.dao.UserDaoImpl"/>
<!-- 注意:不能再有另一个类型为UserDao的bean,否则会报错 -->

原理:Spring会遍历IOC容器中所有的Bean,检查其类型是否与UserServiceImpl中需要注入的属性(如UserDao)类型匹配,如果找到且唯一,则自动注入。

总结

  • IOC​ 是一种设计思想,将对象的控制权交给容器,实现解耦。

  • DI​ 是IOC的一种实现方式,由容器在运行时动态地将依赖关系注入到组件中。

  • 在Spring中,IOC容器通过读取配置(XML或注解)来管理Bean及其依赖关系,DI则负责建立Bean之间的关联。​ 从手写工厂到使用Spring容器,我们看到了这一思想从概念到强大工业级实现的演进过程。

Spring简介与IOC容器 一、Spring简介 开源:源码公开、免费试用; 简化:简化企业级开发。 解耦:耦合度降低、可插拔,便于后续维护更新升级拓展。 二、Sping核心模块 Spring 框架的这些模块可以满足一切企业级应用开发的需求,在开发过程中可以根据需求有选择性地使用所需要的模块。 官网:Spring | Home Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。 Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任. 阅读详情

相关推荐

SAP SD销售订单抬头自定义字段增强:BADI_SLS_HEAD_SCR_CUS实战指南

SAP ERP系统中的销售订单管理是企业核心业务流程,经常需要扩展标准功能来满足个性化业务需求。在SAP SD模块中,销售订单抬头屏幕的增强是常见需求。通过BADI(Business Add-In)技术,可以在不修改标准代码的前提下,实现自定义字段的添加与数据处理。本文详细介绍了如何使用BADI_SLS_HEAD_SCR_CUS实现销售订单抬头自定义字段,包括函数组子屏幕设计、数据存储表构建以及BADI方法的具体实现。这种增强方式适用于VA01/VA02/VA03等事务,保证了系统升级的兼容性和维护的便捷性

weixin_29758911的博客 348

Spring之核心容器(IoC,DI,基本操作)详解

Spring框架的核心是**IoC容器**,它通过控制反转(IoC)和依赖注入(DI)实现对象的管理与依赖解耦,是Spring所有功能的基础。本文我将从核心概念入手,深入解析IoC和DI的原理,并结合实例讲解Spring容器的基本操作(Bean的创建、获取、生命周期管理),带你理解Spring容器的工作机制。

aa_hdkf_vg的博客 1438

STM32HAL库 基于外部Flash+FatFs模拟U盘方式进行固件拷贝升级(详解)

STM32HAL库 基于外部Flash+FatFs模拟U盘方式进行固件拷贝升级

qq_36075612的博客 1万+

Spring核心原理详解:IOC、DI与AOP的实现机制

本文深入解析了Spring框架的核心原理,包括控制反转(IOC)、依赖注入(DI)和面向切面编程(AOP)。IOC通过BeanFactory和ApplicationContext实现组件管理权的反转;DI采用构造器、Setter和字段三种注入方式,通过三级缓存解决循环依赖;AOP基于动态代理技术实现横切关注点的模块化。文章详细阐述了Spring容器的初始化流程、Bean生命周期管理以及自动装配机制,揭示了Spring框架高效管理对象依赖和增强功能的技术内幕。

cx1050306424的博客 3885

(2024,DDPM,DDIM,流匹配,SDE,ODE)扩散:基础教程

本文的目标是尽可能简单地教授扩散。第一节介绍扩散的基本原理。第二节和第三节展示如何构建随机和确定性扩散采样器。第四部分介绍了密切相关的流匹配,可看作是扩散的推广。​第五节,强调实践中最重要的一些设计选择,包括采样器、噪声时间表和参数化方法。

qq_44681809的博客 1万+

基于STM32的HC-SR04超声波模块测距(新手级)

本人是嵌入式新手,学习了STM32的部分内容,最近想找些项目做,然后顺便学习了一下HC-SR04超声波模块,学习过程中也参考了一些大佬的文章。本文记录了自己的学习方法和学习过程,同时也希望能和各位大佬交流讨论。

weixin_63758495的博客 2203

Spring IOC、DI及AOP详解与实战

本文深入解析Spring框架核心的IOC、DI及AOP概念,以通俗易懂的方式阐述其原理与应用。文章先通过生动比喻介绍IOC(控制反转)概念,对比传统"霸道总裁"式对象创建与Spring"甩手掌柜"式管理;接着讲解依赖倒置原则、Spring容器工作流程,并提供手写简易IOC容器示例;随后阐述DI(依赖注入)与IOC的关系及实现方式。整体语言风趣,结构清晰,注重实战应用,帮助读者掌握Spring精髓。

码道源码 1114

华为OD机试真题 新系统 2026-06-10 C++ 实现【设备重排SN】

通信设备SN一般是包含:字母、数字,用'-'(破折号)进行分组分割,例如:8F-3T-1G-2n是一个有效的SN地址。 现在要对已经存在的SN 按照新的规则进行重排:

MISAYAONE的博客 129

【Spring】重构--手写Spring核心逻辑(二)实现IOC/DI(beans包)

MYBeanDefinition 用来保存Bean的信息,包括实际类信息和配置信息。在我们平时使用Spring时,xml中有许多能配置的选项,但是为了简单我们这里只包括了 class,factory,method,lazyInit 这四项。 在通过getBean获取Bean实例时,首先要拿到这里实例的类信息(BeanDefinition)。 对应关系: 一个Class对应多个BeanDefinition,比如Abean,Bbean属于同一class的实例,但一个是懒加载,一个不是懒加载 一个BeanDe

A minor 2790

1. BES2700ZP概述

恒玄BES2700采用RTX5操作系统,配合mindmics算法或者自研算法。

雪飞_海 4464

1. 如何使用扣子工作流一键生成儿童绘本(可以发到小红书,微信公众号图文等)

本文介绍了使用扣子智能体一键生成儿童绘本的工作流。用户只需输入绘本主题,系统会自动生成Markdown格式内容,可直接发布到优快云、小红书等平台,还支持推送至微信公众号草稿箱。操作步骤包括:访问扣子网站导入工作流源代码,输入主题试运行,查看实时进度和最终输出结果。工作流编辑器会显示每个节点的执行状态和耗时,支持通过"查看日志"功能回溯历史运行记录。文末附有工作流源代码下载链接。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1244

Spring IoC容器

核心技术 发行版5.0.8 这一部分的指导文档覆盖了所有的完全集成到Spring框架中的技术。 这些技术中首要的便是Spring框架的控制反转(IoC)容器。Spring框架的IoC容器的全面的处理是与Spring的面向切面编程(AOP)的彻底实现紧密相关的。Spring框架拥有他自己的AOP框架,该技术在概念上是很容器理解的,并且成功的解决了在Java企业编程中的AOP需求的80%的点。 该框...

hongbochen1223的专栏 1万+

【RT-DETR多模态融合改进】| 自研 多模态大核选择模块:MM_LSK,适配多模态图像信息融合

本文记录的利用改进的多模态大核选择模块(MM-LSK)优化RT-DETR,构建可见光-红外双模态目标检测网络。在遥感等大尺寸图像的可见光-红外双模态小目标检测任务中,单模态检测易受光照、云雾、背景干扰等因素影响,且小目标外观信息匮乏,无法仅基于单模态外观实现较好的识别,因此需要融合双模态互补特性与广泛的跨模态上下文信息进行辅助。

Limiiiing的博客 381

Spring 核心之 IOC 容器学习一

IOC 与 DI IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创建、依赖的代码,反转给容器来帮忙实现。那么必然的我们需要创建一个容器,同时需要一种描述来让容器知道需要创建的对象与对象的关系。这个描述最具体表现就是我们所看到的配置文件。DI(Dependency Injection)依赖注入:就是指对象是被动接受依赖类而不是自己主动去找,换句话说就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象的时候主动将它依赖的类注入给它。 1、对象

lssffy的博客 1448

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【Spring IoC & DI】深入解析 IoC & DI :Spring框架的核心设计思想和 IoC 与 DI 的思想和解耦优势

【Spring IoC & DI】深入解析 IoC & DI :Spring框架的核心设计思想和 IoC 与 DI 的思想和解耦优势 ioC & DI 入门 Spring是什么? 什么是容器? 什么是ioC? ioC 介绍 传统程序开发 问题分析 解决方案 ioC 程序开发 ioC 优势 DI 介绍

OuO-1 的博客 1326

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Spring——IoC和DI

目录一、初识Spring为什么要使用Spring什么是SpringSpring框架的核心由哪些模块组成二、Core Container(核心容器)IoC(控制反转)什么是 IoCIoC 的作用IoC 的优点IoC 的缺点DI(依赖注入)什么是DI依赖注入的基本原则依赖注入的优势不同类型的依赖注入实现方式构造器依赖注入和 Setter方法注入的区别顶级接口BeanFactory 和 ApplicationContext 的区别BeanFactory和ApplicationContext的关系详解Applica

浪漫不死的博客 3897

Spring(ioc和di)简介

(以前我们要自己new对象,现在spring帮我们new对象,以后我们需要对象,就找spring要) 以前:做鞋子--手工作坊 (自己new对象) 1、效率低 2、每个细节都要关注 3、成本高----人力 ,时间 现代:工厂 (spring bean工厂---new对象) 1、效率高 2、不需要关注每个细节,机器 3、成本低

Lans2716的博客 4569

Spring框架:简述IOC与DI

在传统的软件开发模式中,当一个类需要依赖多个对象时,开发者就如同勤劳的“搬砖工”,必须手动使用new关键字创建出所有依赖的对象。例如,想要使用,就需要,而若依赖UserDao,又得。然而,一旦这些依赖对象的实现类发生变化,所有使用到它们的地方都得一一修改,就像牵一发而动全身的复杂棋局,让人头疼不已。

2401_86968005的博客 1033

Spring IoC/DI

Bean对象的实例化方式,Spring属性注入的方法,Bean的生命周期,注解在Spring上的使用

2401_88007700的博客 2236

Java 手写 Spring框架 IOC 和 AOP----手写Spring IoC和AOP

本文将首先通过手写Spring,了解Spring基本思想,然后介绍Spring的一些高级用法,随后深度剖析其源码,让读者有更深入的了解====本文源码基于5.1.12版本讲解

殷志鹏的博客 2541

手写Spring IoC:注解+反射打造轻量级容器

本文介绍如何通过注解和反射机制手写一个简易版Spring IoC容器,深入理解其核心原理。首先定义@Component、@Autowired等核心注解,然后实现包扫描器查找标记类。通过反射机制动态创建Bean实例并管理依赖注入,模拟Spring容器的核心功能。文章详细讲解了控制反转和依赖注入的概念,以及如何利用Java反射实现自动装配。通过这个实践项目,读者可以掌握Spring IoC的底层实现机制,提升对框架设计的理解能力。整个过程涵盖了注解定义、类扫描、Bean创建和依赖注入等关键环节,是学习Sprin

qq_41262225的博客 1017

Spring(5)——IoC & DI

在早期的开发中和对于初学者的学习过程中,整个项目中对象的数量不多,对象的属性不多,对象之间的依赖不强。但是随着技术的发展,一个项目中对象数量越来越多,属性越来越多,对象之间的依赖也越来越复杂。甚至于多个对象构成一个组件,组件之间的依赖也很复杂。此时我们就需要一个平台,平台负责对象的生成和装配。作为开发者我们只需要将对象的生产方法告诉平台,即更多的关注功能的实现。

qq_46209845的博客 1099

深入理解Spring核心:IOC/DI原理与AOP事务管理

本文深入探讨了Spring框架的两大核心特性:IOC/DI(控制反转/依赖注入)和AOP(面向切面编程)的事务管理机制。首先,文章详细解析了IOC/DI的原理,包括控制反转的概念、依赖注入的三种方式(构造器注入、Setter注入、字段注入)以及Spring容器的核心实现原理,特别是如何通过三级缓存解决循环依赖问题。

qq_57755194的博客 1631

透析Spring(一): Spring之IoC容器理解

看懂Spring的IoC容器设计思路,好处,并和DI进行比较等

Java学习之道 4020

为什么学习Spring,什么是Spring,什么是IOC,什么是DI,什么是容器

什么是Spring Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(nverse Of Control:反转控制) 和 AOP(Aspect Oriented Programming:面向切面编程) 为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的...

Alphr的博客 769

[2025]关于spring的ioc和aop?ioc和DI的区别,ioc是怎么实现的?aop是怎么实现的?

ioc的好处1:使用者不用关心引用bean的实现细节,譬如对于A a = new A(c,d,e,f);来说,如果要使用A,那还要把c,d,e,f多个类全都感知一遍,这显然是非常麻烦且不合理的 2:不用创建多个相同的bean导致浪费。 3:Bean的修改使用方无需感知。同样是上面的例子,假如说BeanA需要修改,如果没有IOC的话,所有引用到A的其他bean都需要感知这个逻辑,并且做对应的修改。但是如果使用了IOC,其他bean就完全不用感知到对于Spring的IOC来说,它是IOC思想的一种实现方式。

gwndjsh的博客 1542
上一篇: JDBC全套核心知识点整理(从入门到封装)
下一篇: Spring核心知识精讲:IoC容器、Bean作用域生命周期与AOP(第二部分)
StackNoOverflow
博客等级 码龄1年 22粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值