Spring IOC 容器详解

2023-11-12

目录

1、容器的概念

2、如何配置元数据

3、如何实例化一个容器

4、使用容器


1、容器的概念

        ApplicationContext 代表 Spring IoC 容器,它负责 Spring Beans 的实例化、配置和组装。容器通过读取配置元数据//配置文件)获取关于要实例化、配置和组装哪些对象的指令。配置元数据可以用 XML、Java 注释或 Java 代码表示。通过配置文件可以定义组成应用程序的对象以及这些对象之间复杂的依赖关系。// 容器通过配置文件来定义 Bean 的创建

        Spring 提供了 ApplicationContext 接口的几个实现,例如 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext,虽然 XML一直是配置元数据的传统方式,但是也可以指示 Spring 容器使用 Java 注释或 Java 代码作为配置元数据的方式,不过,这也需要借助少量 XML 配置,以声明的方式启用对这些额外元数据格式的支持。// 配置文件可以有多种格式 xml、java 注释、java 代码

        在大多数应用程序场景中,不需要显式的去创建 Spring IoC 容器的实例。例如,在 web 应用程序场景中,通常只需要一个简单的 web.xml 样板配置文件就足够了。这个 xml 文件非常简单,大概只有 8 行的样子(web.xml文件)。如果你使用 Spring Tools for Eclipse,创建这样的样板配置将会更加简单。// 大多数场景,不需要显式的去实例化 Spring IoC 容器,那又是怎么实例化的呢?

        下图显示了 Spring 如何工作的高级视图。应用程序的类与配置元数据相结合,当 ApplicationContext 通过配置元数据创建并初始化 Beans 之后,就拥有了一个基于配置的和可执行的应用程序。

2、如何配置元数据

        如上图所示,Spring IoC 容器使用配置元数据创建对象。该配置元数据的作用就是定义 Spring 容器如何实例化、配置和组装应用程序中的对象。

        xml 文件是 Spring 传统的配置文件,虽然 xml 配置文件逐渐被 java 配置文件所代替,但文章中大部分例子还是会用到 xml 文件的配置形式。其他格式的配置文件方式可参考:

        Spring 容器的配置文件通常由一个或多个 Bean 定义组成(容器管理 Bean),基于 xml 的配置元数据将这些 bean 配置为顶层 <beans/> 标签中的 <bean/> 元素。而基于 Java 代码的配置通常在 @Configuration 类中使用 @ bean 注释来定义一个 bean。// 如何定义一个 bean

        bean 定义与组成应用程序的实际对象层一一对应。比如,定义服务层对象、数据访问层对象(dao)、表示层对象(如 Struts Action 实例)、基础结构对象(如 Hibernate SessionFactories、JMS 队列等)。但是,一般都不需要在容器中配置非常细粒度的域对象(//具体的用户对象,如用户A\B\C),因为创建和加载域对象通常是 dao 和业务逻辑层的责任。另外,也可以使用 Spring 与 AspectJ 的集成来配置在 IoC 容器控制之外创建的对象// IoC 容器控制之外的对象,AOP 是管理还是配置?如何配置的?

        下面的例子展示了基于 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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>
  • id 属性是标识单个 bean 定义的字符串。
  • class 属性定义 bean 的类型,并使用完全限定的类名。

3、如何实例化一个容器

        提供给 ApplicationContext 构造函数位置路径或资源字符串路径,允许容器从各种外部资源加载配置元数据,例如本地文件系统、Java ClassPath 等等。// 显示的创建了容器,通过指定文件路径加载配置资源

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

下面的示例显示了服务层对象( services.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- services -->

    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

下面的示例显示了数据访问对象 daos.xml 文件: // 每一层都对应一个 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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao"
        class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- 此bean的其他配置和属性配置在这里 -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

        在上边的示例中,服务层由 PetStoreServiceImpl 类,以及 JpaAccountDao 和 JpaItemDao 类型的两个数据访问对象(基于 JPA 对象-关系映射标准)组成。property name 元素引用 JavaBean 属性的名称,ref 元素引用另一个 bean 定义的名称。id 和 ref 元素之间的链接表示协作对象之间的依赖关系。// 对象之间依赖关系的定义

编写基于 xml 的配置元数据

        让 bean 定义跨越多个 XML 文件有时候是非常有用的。通常,每个单独的 XML 配置文件代表体系结构中的一个逻辑层或模块。

        你可以使用 ApplicationContext 构造函数从所有这些分开的 XML 配置文件中加载 bean 定义。因为 ApplicationContext 构造函数可以接受多个 Resource 位置作为参数。或者,使用 <import/> 标签也可以从一个或多个配置文件中加载 bean 定义。下面的例子展示了如何做到这一点: // 加载多个配置文件的两种方式,其中 import 在Spring boot 中被广泛使用

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

        在上边的示例中,外部 bean 定义从三个文件中加载:services.xml、messageSource.xml 和 themeSource.xml。所有位置路径都是相对于执行导入的定义文件//定义<import/> 标签的文件)来定义位置的,因此,services.xml 必须与执行导入的文件位于相同的目录或类路径位置,messageSource.xml 和 themeSource.xml 必须位于导入文件位置以下的资源位置。如你所见,前面的斜杠被忽略了。然而,考虑到这些路径是相对的,最好完全不使用斜杠。根据Spring Schema,导入的文件的内容(包括顶层 <beans/> 元素)必须是有效的 XML bean 定义。// 配置文件位置定义有多种形式,同时 xml 配置文件内容有严格的格式规定

        可以(但不建议)使用相对路径 “../” 引用父目录中的文件,因为这样做会创建对当前应用程序之外的文件的依赖。特别是,不建议对类路径:URLs(例如,classpath:../services.xml )使用此引用,在这种情况下,运行时解析过程将选择“最近的”类路径根目录,然后查找它的父目录。类路径的更改可能导致选择不同的、错误的目录。// 类移动了,父目录也跟着改变,但是资源文件位置没有改变,导致程序读不到资源文件

        推荐使用完全绝对路径而不是相对路径,比如 file:C:/config/services.xml 或者 classpath:/config/services.xml。但是,请注意,这样会将应用程序的配置耦合到特定的绝对位置。对于这种绝对位置,一般最好使用一个间接的方向,例如,使用在运行时根据 JVM 系统属性解析的 “${…}” 占位符。// 使用绝对位置时,通过占位符来进行配置

        命名空间本身提供了导入指令特性。除了普通 bean 定义之外,在 Spring 提供的 XML 名称空间选择中还提供了更多的配置特性,比如,context 和 util 命名空间。// 这些是啥?应该不重要?

4、使用容器

        ApplicationContext 是一个高级的 Bean 工厂,维护了不同 bean 的注册表和他们之间的依赖关系。通过使用方法 T getBean (字符串名称,Class<T> requiredType),可以获取到 bean 的实例。// getBean() 获取容器中的实例

        ApplicationContext 允许你读取 bean 定义并访问它们,如下面的示例所示:

// 创建和配置 beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// 获取配置的实例
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// 使用配置的实例
List<String> userList = service.getUsernameList();

        最灵活的 ApplicationContext 变体是 GenericApplicationContext 的读取委派,例如,使用XmlBeanDefinitionReader 用于读取 XML 配置文件,如下例所示:

// 通用上下文
GenericApplicationContext context = new GenericApplicationContext();
// Reader 读取器
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
// 刷新上下文
context.refresh();

        你也可以为 Groovy 文件使用 GroovyBeanDefinitionReader,如下面的例子所示:

GenericApplicationContext context = new GenericApplicationContext();
// Groovy 文件读取器
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
// 刷新上下文
context.refresh();

        通过这种方式可以在同一个 ApplicationContext 上混合和匹配阅读器委托,从不同的配置源读取 bean 定义。// 使用阅读器委托可以从不同类型文件中读取 bean 定义

        虽然 ApplicationContext 接口提供一些用于获取 bean 的方法,用户可以使用 getBean 获取 bean 的实例,但通常情况下,应用程序代码不应该使用它们。实际上,应用程序代码也完全没有对 getBean() 方法的调用,完全不依赖 Spring API 。例如,Spring 与 web 框架集成,为各种 web框架组件(如控制器和 jsf 管理的 bean )提供了依赖注入,允许你通过元数据(例如自动装配注释)声明对特定 bean 的依赖。// 自动注入,那么 Spring 如何进行自动注入的呢?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring IOC 容器详解 的相关文章

随机推荐

  • Unity使用tolua框架教程: LuaFramewrk

    一 tolua下载 二 运行Demo 1 生成注册文件 2 将lua打成AssetBundle 3 解决报错 4 为何一些没有在CustomSettings cs注册的类也会生成Wrap类 5 顺利生成AssetBundle 6 运行Dem
  • 程序编写好后,编译无错误无警告,各项配置也没有错,但下载程序就出现了这个错误Error: Flash Download failed - Could not load file ''...

    这个错误通常是由于下载程序文件不存在或不可用导致的 请检查文件路径是否正确 文件是否存在并且可读 如果文件路径是通过网络获取的 请检查网络连接是否正常 另外 请确保程序已经正确配置 并且编译后的二进制文件已经生成
  • 整理

    1 请将字符串逆序 如 aabbccddeeff 转化成为 ffeeddccbbaa include
  • day10-JavaScript核心语法(补充)/函数

    0目录 1 JavaScript核心语法 补充 2 函数 1 JavaScript核心语法 补充 1 7 逻辑控制语句 4 while循环 while语句只要指定条件为true 就会执行循环 只要指定条件为True 循环就可一直执行代码 5
  • 二叉树深度和高度_二叉树的高度和深度

    二叉树深度和高度 In this tutorial we will learn how to find height and depth of binary tree with program implementation in C It
  • 渲染基础理论的介绍(1)

    渲染基础理论的介绍 1 http www qiujiawei com rendering equation Tags math computer graphics 基础概念 辐射度学 Radiometry 辐射度学是指测量电磁辐射 包括可见
  • 「PAT乙级真题解析」Basic Level 1045 快速排序 (问题分析+完整步骤+伪代码描述+提交通过代码)

    乙级的题目训练主要用来熟悉编程语言的语法和形成良好的编码习惯和编码规范 从小白开始逐步掌握用编程解决问题 PAT乙级BasicLevelPractice 1045 问题分析 题设要求所有给定数列中的满足主元条件的元素 主元条件 这个元素大于
  • mysql 显示所有用户_mysql查看全部用户

    mysql查看所有用户 声明 以下内容是读MySQL The Complete Reference的笔记 1 创建数据库 create database db1 2 为防止重复 create database if not exists d
  • UltraEdit 换行替换

    需求 想在每行结尾添加 方案 在查找栏填写 r n 替换栏 r n 效果 转载于 https www cnblogs com qianyuliang p 7793007 html
  • torch、torch.nn、 torch.optim、torchvision、 torchvision.transforms 功能简介

    1 torch 库 import torch 命令将 PyTorch 框架导入到 Python 程序中 这样我们就可以使用 PyTorch 提供的各种功能了 PyTorch 是一个用于科学计算的机器学习库 具有以下重要功能 张量 Tenso
  • 发布一个在读写sd卡时,此时sd卡拔出造成死机的处理方法

    发布一个在读写sd卡时 此时sd卡拔出造成死机的处理方法 同时也在此记录一下 以备后用及有需要人们参考 stm32f4xx hal sd c 红色的代码是增加上去的 函数名称 static HAL SD ErrorTypedef SD Cm
  • TenserRT(七): TensorRT Python实战

    1 生成ONNX import torch import UNetTrainer dev nb 0 model file r xxx model trainer UNetTrainer dev nb dim 2 trainer load m
  • vue路由 & nodeJS环境搭建

    目录 一 路由 1 SPA是什么 优势 2 SPA实现思路和技术点 路由步骤 1 引入Vue vue router的js依赖 2 定义组件 就是展示不同的页面效果 3 定义路由与组件的对应关系 4 生成路由对象 5 将Vue对象挂载到Vue
  • Python文件读写和函数编程

    文件读写 在Python中 文件的操作应用非常多 比如大数据领域 涉及许多数据处理请求 基本上都是从一个文件对数据进行分析 抽取 重写进行梳理数据 文件的读写分几步 如何把大象放冰箱 下面我们来拆分下 打开文件 python中打开文件使用o
  • 生成进度条(动态生成文件,并前端显示生成进度)

    注 1 本文是以生成txt文件为例子 2 写的主要是一个思路 不一点非要是生成txt 可以是其他类型文件 3 本文例子的项目地址 https github com smallsnail wh wh 思路 在前端显示 需要拿到生成的进度 百分
  • 正向代理与方向代理的区别

    之前工作用到了nginx 很好理解反正代理 但是正向代理一直困扰这我 今天终于拨开乌云见晴天 正向代理 代理的是客户端 比如 我不能访问公司的内网 然后使用了vpn登录到跳板机 最后成功访问了就是正向代理 反向代理 代理的是服务端 比如 我
  • 模块独立性的度量(耦合度和内聚度)

    模块独立性的度量 从两个方面来度量模块之间的独立性 这两个概念是模块的耦合度和模块的内聚度 耦合度 耦合度分为 独立耦合 数据耦合 控制耦合 公共耦合 和 内容耦合 独立耦合 指两个模块之间彼此完全独立 没有直接联系 他们之间的联系仅仅在于
  • pandas中pd.read_excel()的用法

    人们经常用pandas处理表格型数据 时常需要读入excel表格数据 很多人一般都是直接这么用 pd read excel 文件路径文件名 再多一点的设置可能是转义一下路径中的斜杠 一旦原始的excel表不是很规整 这样简单读入势必报错 其
  • Ain_电脑所有乱码文字集

    以下是所有电脑上可显示的汉字 谁要是用哪个又通过输入法输不出来 可以从这里找 很简单 就是把int的 19968 至 40869 的数字按字符输出即可 19968 一丁丂七丄丅丆万丈三上下丌不与丏丐丑丒专且丕世丗丘丙业丛东丝丞丟 20000
  • Spring IOC 容器详解

    目录 1 容器的概念 2 如何配置元数据 3 如何实例化一个容器 4 使用容器 1 容器的概念 ApplicationContext 代表 Spring IoC 容器 它负责 Spring Beans 的实例化 配置和组装 容器通过读取配置