Spring Ioc 容器介绍

本章介绍 Spring 的控制反转 (IoC) 容器。

该接口表示 Spring IoC 容器,并负责实例化、配置和组装 Bean。 容器获取有关组件的指令,以实例化、配置和 通过读取配置元数据进行组装。可以表示配置元数据 作为带注释的组件类、具有工厂方法的配置类或外部 XML 文件或 Groovy 脚本。使用任何一种格式,您都可以编写您的应用程序和 这些组件之间具有丰富的相互依赖性。org.springframework.context.ApplicationContext

该接口的几个实现是核心 Spring 的一部分。 在独立应用程序中,通常创建 AnnotationConfigApplicationContext 或 ClassPathXmlApplicationContext 的实例。ApplicationContext

在大多数应用程序方案中,不需要显式用户代码来实例化一个或 Spring IoC 容器的更多实例。例如,在纯 Web 应用程序方案中, 应用程序文件中的简单样板 Web 描述符 XML 就足够了(请参阅 Web 应用程序的方便 ApplicationContext 实例化)。 在 Spring Boot 方案中,应用程序上下文是隐式引导的 基于通用设置约定。web.xml

下图显示了 Spring 工作原理的高级视图。您的应用程序类 与配置元数据结合使用,因此,在 创建并初始化后,您就拥有了完全配置且可执行的系统或应用程序。ApplicationContext

容器魔术

图 1.Spring IoC 容器

配置元数据

如上图所示,Spring IoC 容器使用 配置元数据。此配置元数据表示您作为 应用程序开发人员,告诉 Spring 容器实例化、配置、 并在您的应用程序中组装组件。

Spring IoC 容器本身与以下格式完全分离 配置元数据实际上是写入的。如今,许多开发人员为他们的 Spring 应用程序选择基于 Java 的配置

Spring 配置由至少一个(通常不止一个)bean 定义组成 容器必须管理。Java 配置通常使用 -annotated 类中的方法,每个方法对应一个 Bean 定义。@Bean@Configuration

这些 Bean 定义对应于构成应用程序的实际对象。 通常,您可以定义服务层对象、持久性层对象,例如 存储库或数据访问对象 (DAO)、表示对象(如 Web 控制器)、 基础结构对象,如 JPA 、 JMS 队列等。 通常,不会在容器中配置细粒度域对象,因为 创建和加载通常是存储库和业务逻辑的责任 域对象。EntityManagerFactory

XML 作为外部配置 DSL

基于 XML 的配置元数据将这些 Bean 配置为内部的元素 顶级元素。以下示例显示了 基于 XML 的配置元数据:<bean/><beans/>

<span style="color:#191e1e"><span style="background-color:#ffffff"><code class="language-xml"><span style="color:var(--highlight-meta-font-color)"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">beans</span> <span style="color:var(--highlight-tag-attribute-font-color)">xmlns</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xmlns:xsi</span>=<span style="color:var(--highlight-string-font-color)">"http://www.w3.org/2001/XMLSchema-instance"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xsi:schemaLocation</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"..."</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"..."</span>></span>  
		<span style="color:var(--highlight-comment-font-color)"><!-- collaborators and configuration for this bean go here --></span>
	<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">bean</span>></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"..."</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"..."</span>></span>
		<span style="color:var(--highlight-comment-font-color)"><!-- collaborators and configuration for this bean go here --></span>
	<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">bean</span>></span>

	<span style="color:var(--highlight-comment-font-color)"><!-- more bean definitions go here --></span>

<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">beans</span>></span></code></span></span>
Copied!
该属性是一个字符串,用于标识单个 Bean 定义。id
该属性定义 Bean 的类型,并使用完全限定的 类名。class

该属性的值可用于引用协作对象。The XML 此示例中未显示用于引用协作对象。有关详细信息,请参阅依赖项id

用于实例化容器,XML 资源文件的位置路径 需要提供给一个构造函数,该构造函数让 来自各种外部资源的容器加载配置元数据,例如 作为本地文件系统、Java 等。ClassPathXmlApplicationContextCLASSPATH

  • Java

  • Kotlin

<span style="color:#191e1e"><span style="background-color:#ffffff"><span style="background-color:initial"><code class="language-java">ApplicationContext context = <span style="color:var(--highlight-keyword-font-color)">new</span> ClassPathXmlApplicationContext(<span style="color:var(--highlight-string-font-color)">"services.xml"</span>, <span style="color:var(--highlight-string-font-color)">"daos.xml"</span>);</code></span></span></span>
Copied!

在了解了 Spring 的 IoC 容器之后,您可能想更多地了解 Spring 的抽象(如 参考资料 中所述) 它提供了一种方便的机制,用于从定义的位置读取 InputStream 在 URI 语法中。具体而言,路径用于构造应用程序上下文, 如应用程序上下文和资源路径中所述。ResourceResource

以下示例显示了服务层对象配置文件:(services.xml)

<span style="color:#191e1e"><span style="background-color:#ffffff"><code class="language-xml"><span style="color:var(--highlight-meta-font-color)"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">beans</span> <span style="color:var(--highlight-tag-attribute-font-color)">xmlns</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xmlns:xsi</span>=<span style="color:var(--highlight-string-font-color)">"http://www.w3.org/2001/XMLSchema-instance"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xsi:schemaLocation</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span>

	<span style="color:var(--highlight-comment-font-color)"><!-- services --></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"petStore"</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"org.springframework.samples.jpetstore.services.PetStoreServiceImpl"</span>></span>
		<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">property</span> <span style="color:var(--highlight-tag-attribute-font-color)">name</span>=<span style="color:var(--highlight-string-font-color)">"accountDao"</span> <span style="color:var(--highlight-tag-attribute-font-color)">ref</span>=<span style="color:var(--highlight-string-font-color)">"accountDao"</span>/></span>
		<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">property</span> <span style="color:var(--highlight-tag-attribute-font-color)">name</span>=<span style="color:var(--highlight-string-font-color)">"itemDao"</span> <span style="color:var(--highlight-tag-attribute-font-color)">ref</span>=<span style="color:var(--highlight-string-font-color)">"itemDao"</span>/></span>
		<span style="color:var(--highlight-comment-font-color)"><!-- additional collaborators and configuration for this bean go here --></span>
	<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">bean</span>></span>

	<span style="color:var(--highlight-comment-font-color)"><!-- more bean definitions for services go here --></span>

<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">beans</span>></span></code></span></span>
Copied!

以下示例显示了数据访问对象文件:daos.xml

<span style="color:#191e1e"><span style="background-color:#ffffff"><code class="language-xml"><span style="color:var(--highlight-meta-font-color)"><?xml version="1.0" encoding="UTF-8"?></span>
<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">beans</span> <span style="color:var(--highlight-tag-attribute-font-color)">xmlns</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xmlns:xsi</span>=<span style="color:var(--highlight-string-font-color)">"http://www.w3.org/2001/XMLSchema-instance"</span>
	<span style="color:var(--highlight-tag-attribute-font-color)">xsi:schemaLocation</span>=<span style="color:var(--highlight-string-font-color)">"http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd"</span>></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"accountDao"</span>
		<span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao"</span>></span>
		<span style="color:var(--highlight-comment-font-color)"><!-- additional collaborators and configuration for this bean go here --></span>
	<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">bean</span>></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"itemDao"</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"org.springframework.samples.jpetstore.dao.jpa.JpaItemDao"</span>></span>
		<span style="color:var(--highlight-comment-font-color)"><!-- additional collaborators and configuration for this bean go here --></span>
	<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">bean</span>></span>

	<span style="color:var(--highlight-comment-font-color)"><!-- more bean definitions for data access objects go here --></span>

<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">beans</span>></span></code></span></span>
Copied!

在前面的示例中,服务层由类组成 和两个类型的数据访问对象 (基于 在 JPA 对象关系映射标准上)。该元素是指 JavaBean 属性的名称,该元素引用另一个 Bean 的名称 定义。和元素之间的这种联系表达了 协作对象。有关配置对象依赖关系的详细信息,请参阅依赖关系。PetStoreServiceImplJpaAccountDaoJpaItemDaoproperty namerefidref

编写基于 XML 的配置元数据

让 Bean 定义跨越多个 XML 文件会很有用。通常,每个人 XML 配置文件表示体系结构中的逻辑层或模块。

您可以使用构造函数从以下位置加载 Bean 定义 XML 片段。此构造函数采用多个位置,如上一节所示。或者 使用元素的一个或多个匹配项从中加载 Bean 定义 另一个文件或文件。以下示例演示如何执行此操作:ClassPathXmlApplicationContextResource<import/>

<span style="color:#191e1e"><span style="background-color:#ffffff"><code class="language-xml"><span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">beans</span>></span>
	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">import</span> <span style="color:var(--highlight-tag-attribute-font-color)">resource</span>=<span style="color:var(--highlight-string-font-color)">"services.xml"</span>/></span>
	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">import</span> <span style="color:var(--highlight-tag-attribute-font-color)">resource</span>=<span style="color:var(--highlight-string-font-color)">"resources/messageSource.xml"</span>/></span>
	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">import</span> <span style="color:var(--highlight-tag-attribute-font-color)">resource</span>=<span style="color:var(--highlight-string-font-color)">"/resources/themeSource.xml"</span>/></span>

	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"bean1"</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"..."</span>/></span>
	<span style="color:var(--highlight-tag-font-color)"><<span style="color:var(--highlight-tag-font-color)">bean</span> <span style="color:var(--highlight-tag-attribute-font-color)">id</span>=<span style="color:var(--highlight-string-font-color)">"bean2"</span> <span style="color:var(--highlight-tag-attribute-font-color)">class</span>=<span style="color:var(--highlight-string-font-color)">"..."</span>/></span>
<span style="color:var(--highlight-tag-font-color)"></<span style="color:var(--highlight-tag-font-color)">beans</span>></span></code></span></span>
Copied!

在前面的示例中,外部 Bean 定义是从三个文件加载的:、 和 。所有位置路径都是 相对于进行导入的定义文件,因此必须在 与执行导入的文件相同的目录或类路径位置,而 和 必须位于 导入文件的位置。如您所见,前导斜杠被忽略。但是,鉴于 这些路径是相对的,最好不要使用斜杠。这 要导入的文件的内容(包括 top level 元素)必须 是有效的 XML bean 定义,根据 Spring Schema。services.xmlmessageSource.xmlthemeSource.xmlservices.xmlmessageSource.xmlthemeSource.xmlresources<beans/>

可以(但不建议)使用 相对“../“路径。这样做会创建对当前文件之外的文件的依赖关系 应用。特别是,不建议对 URL (对于 例如,其中运行时解析过程选择 “Nearest”类路径根目录,然后查看其父目录。类路径 配置更改可能会导致选择不同的不正确目录。classpath:classpath:../services.xml

您始终可以使用完全限定的资源位置而不是相对路径:for 示例,或者 .但是,是 意识到您正在将应用程序的配置耦合到特定的绝对值 地点。通常最好为这种绝对值保留间接性 位置 — 例如,通过针对 JVM 解析的“${...}”占位符 运行时的系统属性。file:C:/config/services.xmlclasspath:/config/services.xml

命名空间本身提供 import 指令功能。进一步 除了普通 Bean 定义之外,还可以在一系列配置中提供 的 XML 命名空间,例如,和 命名空间。contextutil

Groovy Bean 定义 DSL

作为外部化配置元数据的进一步示例,Bean 定义还可以 在 Spring 的 Groovy Bean Definition DSL 中表示,正如 Grails 框架所知道的那样。 通常,此类配置位于“.groovy”文件中,其结构显示在 以下示例:

<span style="color:#191e1e"><span style="background-color:#ffffff"><code class="language-groovy">beans {
	dataSource(BasicDataSource) {
		driverClassName = <span style="color:var(--highlight-string-font-color)">"org.hsqldb.jdbcDriver"</span>
		url = <span style="color:var(--highlight-string-font-color)">"jdbc:hsqldb:mem:grailsDB"</span>
		username = <span style="color:var(--highlight-string-font-color)">"sa"</span>
		password = <span style="color:var(--highlight-string-font-color)">""</span>
		settings = [<span style="color:var(--highlight-string-font-color)">mynew:</span><span style="color:var(--highlight-string-font-color)">"setting"</span>]
	}
	sessionFactory(SessionFactory) {
		dataSource = dataSource
	}
	myService(MyService) {
		nestedBean = { AnotherBean bean ->
			dataSource = dataSource
		}
	}
}</code></span></span>
Copied!

这种配置样式在很大程度上等同于 XML Bean 定义,甚至 支持 Spring 的 XML 配置命名空间。它还允许导入 XML Bean 定义文件。importBeans

该属性是一个字符串,用于标识单个 Bean 定义。id
该属性定义 Bean 的类型,并使用完全限定的 类名。class

在了解了 Spring 的 IoC 容器之后,您可能想更多地了解 Spring 的抽象(如 参考资料 中所述) 它提供了一种方便的机制,用于从定义的位置读取 InputStream 在 URI 语法中。具体而言,路径用于构造应用程序上下文, 如应用程序上下文和资源路径中所述。ResourceResource

可以(但不建议)使用 相对“../“路径。这样做会创建对当前文件之外的文件的依赖关系 应用。特别是,不建议对 URL (对于 例如,其中运行时解析过程选择 “Nearest”类路径根目录,然后查看其父目录。类路径 配置更改可能会导致选择不同的不正确目录。classpath:classpath:../services.xml

您始终可以使用完全限定的资源位置而不是相对路径:for 示例,或者 .但是,是 意识到您正在将应用程序的配置耦合到特定的绝对值 地点。通常最好为这种绝对值保留间接性 位置 — 例如,通过针对 JVM 解析的“${...}”占位符 运行时的系统属性。file:C:/config/services.xmlclasspath:/config/services.xml

使用容器

是先进工厂的接口,能够维护 不同 Bean 及其依赖关系的注册表。通过使用该方法,您可以检索 Bean 的实例。ApplicationContextT getBean(String name, Class<T> requiredType)

允许您读取 Bean 定义并访问它们,如下所示 示例显示:ApplicationContext

  • Java

  • Kotlin

<span style="color:#191e1e"><span style="background-color:#ffffff"><span style="background-color:initial"><code class="language-java"><span style="color:var(--highlight-comment-font-color)"><em>// create and configure beans</em></span>
ApplicationContext context = <span style="color:var(--highlight-keyword-font-color)">new</span> ClassPathXmlApplicationContext(<span style="color:var(--highlight-string-font-color)">"services.xml"</span>, <span style="color:var(--highlight-string-font-color)">"daos.xml"</span>);

<span style="color:var(--highlight-comment-font-color)"><em>// retrieve configured instance</em></span>
PetStoreService service = context.getBean(<span style="color:var(--highlight-string-font-color)">"petStore"</span>, PetStoreService.<span style="color:var(--highlight-keyword-font-color)">class</span>);

<span style="color:var(--highlight-comment-font-color)"><em>// use configured instance</em></span>
List<String> userList = service.getUsernameList();</code></span></span></span>
Copied!

使用 Groovy 配置,引导看起来非常相似。它有不同的背景 实现类,它具有 Groovy 感知能力(但也理解 XML Bean 定义)。 以下示例显示了 Groovy 配置:

  • Java

  • Kotlin

<span style="color:#191e1e"><span style="background-color:#ffffff"><span style="background-color:initial"><code class="language-java">ApplicationContext context = <span style="color:var(--highlight-keyword-font-color)">new</span> GenericGroovyApplicationContext(<span style="color:var(--highlight-string-font-color)">"services.groovy"</span>, <span style="color:var(--highlight-string-font-color)">"daos.groovy"</span>);</code></span></span></span>
Copied!

最灵活的变体是与阅读器结合使用 委托 — 例如,对于 XML 文件,如下所示 示例显示:GenericApplicationContextXmlBeanDefinitionReader

  • Java

  • Kotlin

<span style="color:#191e1e"><span style="background-color:#ffffff"><span style="background-color:initial"><code class="language-java">GenericApplicationContext context = <span style="color:var(--highlight-keyword-font-color)">new</span> GenericApplicationContext();
<span style="color:var(--highlight-keyword-font-color)">new</span> XmlBeanDefinitionReader(context).loadBeanDefinitions(<span style="color:var(--highlight-string-font-color)">"services.xml"</span>, <span style="color:var(--highlight-string-font-color)">"daos.xml"</span>);
context.refresh();</code></span></span></span>
Copied!

您还可以使用 for Groovy 文件,如下所示 示例显示:GroovyBeanDefinitionReader

  • Java

  • Kotlin

<span style="color:#191e1e"><span style="background-color:#ffffff"><span style="background-color:initial"><code class="language-java">GenericApplicationContext context = <span style="color:var(--highlight-keyword-font-color)">new</span> GenericApplicationContext();
<span style="color:var(--highlight-keyword-font-color)">new</span> GroovyBeanDefinitionReader(context).loadBeanDefinitions(<span style="color:var(--highlight-string-font-color)">"services.groovy"</span>, <span style="color:var(--highlight-string-font-color)">"daos.groovy"</span>);
context.refresh();</code></span></span></span>
Copied!

你可以在同一个上混合和匹配这样的读者委托, 从不同的配置源读取 Bean 定义。ApplicationContext

然后,您可以使用它来检索 Bean 的实例。该接口还有其他一些用于检索 Bean 的方法,但理想情况下,您的应用程序 代码永远不应该使用它们。事实上,你的应用程序代码根本不应该有对该方法的调用,因此根本不依赖于Spring API。例如 Spring 与 Web 框架的集成为各种 Web 提供了依赖注入 框架组件(如控制器和 JSF 管理的 Bean),允许您声明 通过元数据(例如自动连线注释)对特定 Bean 的依赖关系。getBeanApplicationContextgetBean()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值