IoC 控制反转 入门

IoC 概念


IoC (Inversion of Control)也称为依赖项注入(DI)。

控制反转是一个过程,在此过程中,对象仅通过 构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建 Bean 时注入那些依赖项。此过程从根本上讲,是通过使用类的直接构造或诸如服务定位器模式之类的控件来控制其依赖项的实例化或位置的 bean 本身的逆过程(因此称为 Control Inversion)。

换言之:在使用对象时,原本由主动 new 产生对象 改为使用由==外部==提供对象,此过程中对象创建控制权由程序转移到==外部==,此思想称为控制反转。

org.springframework.beansorg.springframework.context 两个包是 Spring Framework 的 IoC 容器的基础。 BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。

ApplicationContext 是 BeanFactory的子接口。它增加了:

  • 更容易与 Spring 的 AOP 功能集成
  • 消息资源处理(用于国际化)
  • 事件发布:Event publication
  • 特定于应用程序层的上下文,例如用于 Web 应用程序的 WebApplicationContext

简而言之,BeanFactory 提供了配置框架和基本功能,而 ApplicationContext 添加了更多企业特定的功能。 ApplicationContextBeanFactory 的完整超集。

在 Spring 中,构成应用程序主干并由 Spring IoC 容器管理的对象称为 Bean。 Bean 是由 Spring IoC 容器实例化,组装和以其他方式管理的对象。否则,bean 仅仅是应用程序中许多对象之一。 Bean 及其之间的依赖关系反映在容器使用的配置元数据中。

IoC 容器


org.springframework.context.ApplicationContext 接口代表 Spring IoC 容器,并负责实例化,配置和组装 Bean。容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。配置元数据以 XML,Java 注解或 Java 代码表示。它使您能够表达组成应用程序的对象以及这些对象之间的丰富相互依赖关系。

Spring 提供了ApplicationContext 接口的几种实现。在独立应用程序中,通常创建ClassPathXmlApplicationContextFileSystemXmlApplicationContext的实例。尽管 XML 是定义配置元数据的传统格式,但是您可以通过提供少量 XML 配置来声明性地启用对这些其他元数据格式的支持,从而指示容器将 Java 注解或代码用作元数据格式。

在大多数应用场景中,不需要实例化用户代码即可实例化一个 Spring IoC 容器的一个或多个实例。例如,在 Web 应用程序场景中,应用程序 web.xml 文件中的大约简单的八行模板 WebDescriptorsXML 通常就足够了。如果使用Spring 工具套件(如基于 Eclipse、IDEA 的开发环境),则只需单击几次鼠标或击键即可创建此配置。

下图显示了 Spring 的工作原理的高级视图。项目中的应用程序类与配置元数据结合在一起,以便在创建和初始化ApplicationContext之后,获取完全配置且可执行的系统或应用程序。

IoC 入门案例(XML)

一、导入 Spring 坐标

pom.xml

xml 复制代码
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.0.13.RELEASE</version>
</dependency>

二、定义 Spring 管理的类(接口)

Service 接口

java 复制代码
public interface BookService {
	public void save();
}

Service 实现

java 复制代码
public class BookServiceImpl implements BookService {
	private BookDao bookDao = new BookDaoImpl();
	public void save() {
		bookDao.save();
	}
}

三、创建 Spring 配置文件

*resources/applicationContext.xml

  • bean 标签表示配置一个 bean
  • id 属性表示给 bean 名字
  • class 属性表示给 bean 定义类型

bean 定义时 id 属性在同一个上下文中不能重复

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   -->
    <bean id="bookDao" class="cn.pangcy.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="cn.pangcy.service.impl.BookServiceImpl" />
</beans>

四、初始化 IoC 容器

App 启动类

  • 通过 new ClassPathXmlApplicationContext 获取容器对象
  • 通过 ctx.getBean("bean Id") 获取对象

通过 getBean 获取的返回值是 Object 对象,需要强制转一下类型

java 复制代码
public class App {
	public static void main(String[] args) {
		// 加载配置文件获取上下文对象,也就是容器对象
		ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

		// 获取资源
		BookService bookServcice = (BookService) ctx.getBean("bookService");
		bookService.save();
	}
}

一、提供依赖对象对应的 setter 方法

声明依赖对象 BookDao, 并抛出外部赋值方法 setBookDao 提供给 Spring IoC 容器进行依赖注入

java 复制代码
public class BookServiceImpl implements BookService {
	
	private BookDao bookDao;
	
	public void save() {
		bookDao.save();
	}
	
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}
}

二、配置 service 与 dao 之间的关系

创建了 bookDao 与 bookService 后,两者之间没有关系,所以 Spring 也不会自动注入依赖。

在 bookService 中添加 property 标签,建立 bookService 下的依赖关系

  • property 标签表示配置当前依赖的 bean
  • name 是 bookService 中声明的属性名,即抛出的 setter 方法的属性
  • ref 是指定了引用哪一个 bean, 这里的值是 bean 的Id, 如下,这里指定的是 bookDao 的 bean Id
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   -->
    <bean id="bookDao" class="cn.pangcy.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="cn.pangcy.service.impl.BookServiceImpl">
	    <!-- 配置依赖关系 -->
		<property name="bookDao" ref="bookDao"/>
	</bean>
</beans>
相关推荐
人间凡尔赛6 分钟前
eBPF + WebAssembly 正在重写服务网格数据平面:2026 云原生架构的“去 Sidecar“革命
后端·云原生·架构
啊哈一半醒12 分钟前
Go 语言 Context 全方位详解:原理、实战与避坑
开发语言·后端·golang
站大爷IP20 分钟前
被 `@staticmethod` 和 `@classmethod` 坑惨了:继承链里它们真的会“变脸”
后端
orient23 分钟前
CompletableFuture 源码深度解析:6 大 API + 链式编排实战
后端
Zane199433 分钟前
map 比推导式快"是真的吗?一文讲透 map、filter、reduce 与 lambda 的真实性能与设计取舍
后端·python
字节跳动数据库39 分钟前
火山引擎 RDS MySQL 向量索引:把高性能向量检索带到 MySQL 上
人工智能·后端·mysql
拖孩1 小时前
用 AI 重解千年观音灵签,做了一个微信小程序,每天摇一摇,命运给你回应
前端·后端·微信小程序
Python私教1 小时前
AI Agent 可观测性不只是日志:一套可回放的多步执行链
人工智能·后端·python
Python私教1 小时前
模型越强越不需要 Skills?我把 AI 编程能力拆成 4 层
人工智能·后端·python
名字还没想好☜2 小时前
Go 的 io.Reader/Writer 组合实战:io.Copy、TeeReader、MultiWriter 优雅处理数据流
开发语言·后端·golang·go·iphone