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

问:聊聊Spring IOC机制

一、IOC概述及作用

IOC(Inversion of Control):即控制反转,是一种设计思想,其核心是将对象的创建、赋值、管理等操作交给代码之外的容器来实现。在传统的编程模式中,对象的创建和依赖关系的管理通常由程序员手动完成,例如使用new关键字创建对象,通过setXxx()方法设置属性值。这种方式存在高耦合、不易维护和扩展的问题。而IOC通过引入一个“第三方”——IOC容器,将对象的控制权交给容器,从而实现了对象之间的解耦,提高了程序的可扩展性和可维护性。

二、Spring IOC机制详解

Spring框架通过IOC机制实现了对象的管理和依赖注入,其核心组件包括Spring容器和配置文件(或注解)。

1. Spring容器

Spring容器是Spring框架的核心,它负责对象的创建、配置、组装和管理。Spring容器提供了两种类型的容器:BeanFactoryApplicationContext。其中,ApplicationContextBeanFactory的子接口,提供了更多的功能,如事件发布、国际化支持等。

Spring容器在启动时会读取配置文件或注解,根据配置创建和管理对象。当需要获取对象时,可以从容器中通过getBean()方法获取。

2. 配置文件

在Spring框架中,通常使用XML文件作为配置文件来定义和管理对象。配置文件中通过<bean>标签来声明对象,包括对象的ID、类名、作用域、初始化方法、销毁方法等属性。

例如:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userDao" class="com.example.dao.UserDaoImpl"/><bean id="userService" class="com.example.service.UserServiceImpl"/></beans>

在上面的配置文件中,定义了两个对象userDaouserService,分别对应UserDaoImplUserServiceImpl类。

3. 依赖注入

依赖注入(Dependency Injection,DI)是IOC的一种实现方式,它允许程序员在代码中声明依赖关系,而由容器在运行时动态地将依赖注入到对象中。Spring框架支持三种依赖注入的方式:构造方法注入、set方法注入和接口注入(不常用)。

  • 构造方法注入:通过构造方法传递依赖对象。这种方式要求被注入的类有对应的构造方法。

    例如:

    public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveService() {userDao.save();System.out.println("userService save method running...");}
    }
    

    在配置文件中,需要指定构造方法的参数:

    <bean id="userService" class="com.example.service.UserServiceImpl"><constructor-arg ref="userDao"/>
    </bean>
    
  • set方法注入:通过setter方法传递依赖对象。这种方式要求被注入的类有对应的setter方法。

    例如:

    public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void saveService() {userDao.save();System.out.println("userService save method running...");}
    }
    

    在配置文件中,通过<property>标签指定setter方法的参数:

    <bean id="userService" class="com.example.service.UserServiceImpl"><property name="userDao" ref="userDao"/>
    </bean>
    
  • 接口注入:不常用,且Spring框架不推荐使用。

三、Spring IOC使用

下面通过一个示例来说明Spring IOC的使用。

1. 创建Maven工程并引入依赖

首先,创建一个Maven工程,并在pom.xml文件中引入Spring框架的依赖。

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.13</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>

2. 创建实体类、Dao接口及实现类

创建一个Student实体类,一个StudentDao接口及其实现类StudentDaoImpl

// Student实体类
package com.example.pojo;public class Student {private int id;private String name;private String address;// 构造方法、getter和setter方法省略
}// StudentDao接口
package com.example.dao;import com.example.pojo.Student;public interface StudentDao {Student findById(int id);
}// StudentDao实现类
package com.example.dao;import com.example.pojo.Student;public class StudentDaoImpl implements StudentDao {@Overridepublic Student findById(int id) {return new Student(id, "程序员", "北京");}
}

3. 编写XML配置文件

src/main/resources目录下创建一个applicationContext.xml文件,并配置StudentDaoStudentService对象。

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="studentDao" class="com.example.dao.StudentDaoImpl"/></beans>

4. 测试从Spring容器获取对象

编写一个测试类来测试从Spring容器中获取对象并调用其方法。

package com.example;import com.example.dao.StudentDao;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTest {@Testpublic void testIOC() {// 1. 创建Spring容器对象ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");// 2. 从容器中获取StudentDao对象StudentDao studentDao = (StudentDao) applicationContext.getBean("studentDao");// 3. 调用StudentDao对象的方法Student student = studentDao.findById(1);System.out.println(student);}
}

5. 运行测试

运行测试类SpringTest中的testIOC方法,观察输出结果。如果一切正常,将会看到从StudentDaoImpl中返回的Student对象的信息。

四、Spring IOC机制解析

Spring IOC机制的底层实现依赖于Spring容器,而Spring容器本质上是一个对象工厂。在Spring框架中,BeanFactory接口是Spring容器的核心接口,它提供了获取Bean的基本功能。ApplicationContext接口是BeanFactory接口的子接口,提供了更多的功能,如事件发布、国际化支持等。

在Spring容器启动时,会读取配置文件或注解,解析并注册Bean定义。当需要获取Bean时,Spring容器会根据Bean的定义创建Bean实例,并注入依赖关系。这个过程涉及到多个类的协同工作,包括BeanDefinitionReaderBeanDefinitionRegistryBeanFactoryPostProcessorBeanPostProcessor等。

在这里插入图片描述

具体来说,Spring容器的工作流程大致如下:

  1. Bean定义的读取和注册:Spring容器通过BeanDefinitionReader读取配置文件或注解,将Bean定义注册到BeanDefinitionRegistry中。
  2. Bean定义的解析:在Bean定义注册完成后,Spring容器会对Bean定义进行解析,包括解析Bean的依赖关系、初始化方法等。
  3. Bean的创建和依赖注入:当需要获取Bean时,Spring容器会根据Bean的定义创建Bean实例,并注入依赖关系。这个过程涉及到BeanWrapperPropertyEditor等类的协同工作。
  4. Bean的初始化:在Bean创建完成后,Spring容器会调用Bean的初始化方法(如果有的话),完成Bean的初始化工作。
  5. Bean的销毁:当Spring容器关闭时,会调用Bean的销毁方法(如果有的话),完成Bean的销毁工作。
五、总结

Spring IOC机制是Spring框架的核心之一,它通过引入IOC容器实现了对象的管理和依赖注入,降低了程序的耦合度,提高了程序的可扩展性和可维护性。通过配置文件或注解,程序员可以声明对象及其依赖关系,而由Spring容器在运行时动态地创建和管理对象。Spring IOC机制的底层实现依赖于Spring容器和多个类的协同工作,包括Bean定义的读取和注册、Bean定义的解析、Bean的创建和依赖注入、Bean的初始化和销毁等步骤。
原文链接→


http://www.mrgr.cn/news/69792.html

相关文章:

  • 【go从零单排】XML序列化和反序列化
  • 【软考】系统架构设计师-计算机系统基础(2):操作系统
  • Maven 中央仓库地址 mvnrepository.com
  • 微信小程序获取上一页的数据
  • Python | Leetcode Python题解之第557题反转字符串中的单词III
  • 跨境云专线:构建高速、安全的全球业务网络
  • npm常用函数定义手册(持续更新)
  • 使用 nsenter 进入 Docker 容器的操作
  • 逆向攻防世界CTF系列21-answer_to_everything
  • 【Rust练习】20.进一步深入特征
  • Debezium系列之:Incremental snapshotting设计原理
  • 临床预测模型-静态诺模/列线图(Nomogram)+校准曲线(Calibration)分析学习
  • 动态规划-两个数组的dp问题——718.最长重复子数组
  • 【leetcode练习·二叉树】用「分解问题」思维解题 I
  • 《PyTorch深度学习快速入门教程》学习笔记(第20周)
  • 计算机网络基本概念总结
  • cherno引擎课 -
  • 计算机网络-1.2分层结构
  • PostgreSQL 开启密码验证插件
  • 医学图像算法之基于Unet的视网膜血管分割
  • 【Lucene】从文本到索引:Lucene如何构建索引
  • 伊洛瓦底江
  • 存贷款调整 20241110
  • Linux进程信号
  • “穿梭于容器之间:C++ STL迭代器的艺术之旅”
  • 【CLIP系列】开篇