在 Spring 配置文件中使用 bean id 和 name 的区别

Posted

技术标签:

【中文标题】在 Spring 配置文件中使用 bean id 和 name 的区别【英文标题】:Difference between using bean id and name in Spring configuration file 【发布时间】:2010-10-26 20:19:43 【问题描述】:

在 Spring 配置文件中的 <bean> 元素上使用 id 属性和 name 属性有什么区别吗?

【问题讨论】:

很难得到如此直截了当的问题和如此直截了当和全面的答案。伟大的。谢谢! 【参考方案1】:

来自Spring reference、3.2.3.1 Naming Beans:

每个 bean 都有一个或多个 id(也 称为标识符或名称;这些 术语指的是同一件事)。这些 id 在 bean 所在的容器。 bean 几乎总是只有一个 id,但如果一个 bean 有多个 id,额外的基本上可以是 被视为别名。

使用基于 XML 的配置时 元数据,您使用 'id' 或 'name' 指定bean的属性 身份标识)。 'id' 属性 允许您精确指定一个 id, 因为它是一个真正的 XML 元素 ID 属性,XML 解析器能够 做一些额外的验证,当其他 元素引用 id;因此,它 是指定 bean 的首选方式 ID。但是,XML 规范 确实限制了字符 在 XML ID 中合法。这通常不是 一个约束,但如果你有需要 使用这些特殊 XML 之一 人物,或想介绍其他 bean 的别名,您也可以或 而是指定一个或多个 bean id, 用逗号 (,) 分隔,分号 (;),或“名称”中的空格 属性。

所以基本上id 属性符合XML id 属性标准,而name 更灵活一些。一般来说,我几乎只使用name。它看起来更像“春天”。

【讨论】:

您更喜欢使用“name”属性,即使您引用的 Spring 参考建议使用“id”属性?即使您更喜欢使用“名称”,如果 Spring 参考另有建议,您也不能将其称为“Spring-y”:) 我知道这很挑剔;)【参考方案2】:

任何一个都可以。这取决于您的需求: 如果您的 bean 标识符包含特殊字符,例如 (/viewSummary.html),则不允许将其作为 bean id,因为它不是有效的 XML ID。在这种情况下,您可以跳过定义 bean id 而提供 bean namename 属性还有助于为您的 bean 定义 aliases,因为它允许为给定 bean 指定多个标识符。

【讨论】:

另外一个用于用你自己的话说出并举例说明为什么可能需要特殊字符。【参考方案3】:

自 Spring 3.1 起,id 属性为 xsd:string,并允许与 name 属性相同的字符范围。

idname 之间的唯一区别是 name 可以包含多个别名,以逗号、分号或空格分隔,而 id 必须是单个值。

来自 Spring 3.2 文档:

在基于 XML 的配置元数据中,您使用 id 和/或 name 属性来指定 bean 标识符。 id 属性允许您只指定一个 id。按照惯例,这些名称是字母数字的(“myBean”、“fooService”等),但也可以是特殊字符。如果要给 bean 引入其他别名,也可以在 name 属性中指定,用逗号 (,)、分号 (;) 或空格分隔。 作为历史记录,在 Spring 3.1 之前的版本中,id 属性被键入为 xsd:ID,这限制了可能的字符。从 3.1 开始,它现在是 xsd:string。请注意,容器仍然强制执行 bean id 唯一性,但不再由 XML 解析器强制执行。

【讨论】:

【参考方案4】:

在 ApplicationContext xml 中定义 Id 和 name 有区别吗?不 从 3.1(spring) 开始,id 也被定义为 xsd:string 类型。 这意味着在 Id 中也允许定义名称中允许的任何字符。 这在 Spring 3.1 之前是不可能的。

为什么在 name 与 Id 相同时使用 name ? 它在某些情况下很有用,例如允许应用程序中的每个组件通过使用特定于该组件本身的 bean 名称来引用公共依赖项。

For example, the configuration metadata for subsystem A may refer to a DataSource via the name subsystemA-dataSource. The configuration metadata for subsystem B may refer to a DataSource via the name subsystemB-dataSource. When composing the main application that uses both these subsystems the main application refers to the DataSource via the name myApp-dataSource. To have all three names refer to the same object you add to the MyApp configuration metadata the following 

<bean id="myApp-dataSource" name="subsystemA-dataSource,subsystemB-dataSource" ..../>

Alternatively, You can have separate xml configuration files for each sub-system and then you can make use of
alias to define your own names.

<alias name="subsystemA-dataSource" alias="subsystemB-dataSource"/>
<alias name="subsystemA-dataSource" alias="myApp-dataSource" />

【讨论】:

【参考方案5】:

让我回答下面的问题

标签上使用id属性和使用name属性有什么区别吗,

没有区别。在 标签上使用 id 或 name 时,您将体验到相同的效果。

怎么做?

id 和 name 属性都为我们提供了一种向 bean 提供标识符值的方法(此时,认为 id 表示 id 而不是标识符)。在这两种情况下,如果您调用applicationContext.getBean("bean-identifier"); ,您将看到相同的结果。

以@Bean 为例,Java 等效于 标记,您不会找到 id 属性。您只能通过 name 属性将标识符值赋予 @Bean。

让我通过一个例子来解释它: 拿这个配置文件,我们称之为spring1.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
  <bean id="foo" class="com.intertech.Foo"></bean>
  <bean id="bar" class="com.intertech.Bar"></bean>
</beans>

Spring 为 Foo f = (Foo) context.getBean("foo"); 返回 Foo 对象 .将上面spring1.xml中的id="foo"替换为name="foo" ,还是会看到同样的结果。

定义您的 xml 配置,例如,

<?xml version="1.0" encoding="UTF-8"?>
<beans ...>
  <bean id="fooIdentifier" class="com.intertech.Foo"></bean>
  <bean name="fooIdentifier" class="com.intertech.Foo"></bean>
</beans>

你会得到 BeanDefinitionParsingException。它会说,这个元素中已经使用了 Bean 名称“fooIdentifier”。顺便说一句,如果您有以下配置,这与您将看到的相同异常 如果将 id 和 name 都保留在 bean 标记中,则称该 bean 具有 2 个标识符。您可以使用任何标识符获得相同的 bean。 以配置为

<?xml version="1.0" encoding="UTF-8"?><br>
<beans ...>
  <bean id="fooById" name="fooByName" class="com.intertech.Foo"></bean>
  <bean id="bar" class="com.intertech.Bar"></bean>
</beans>

以下代码打印为真

FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(...);
Foo fooById = (Foo) context.getBean("fooById")// returns Foo object;
Foo fooByName = (Foo) context.getBean("fooByName")// returns Foo object;
System.out.println(fooById == fooByName) //true

【讨论】:

【参考方案6】:

idname 都是 Spring IOC 容器/ApplicationContecxt 中的 bean 标识符。 id 属性允许您指定一个 id,但使用 name 属性您可以为该 bean 提供别名。

你可以在这里查看弹簧doc。

【讨论】:

以上是关于在 Spring 配置文件中使用 bean id 和 name 的区别的主要内容,如果未能解决你的问题,请参考以下文章

Spring讲解二:Spring中的Bean配置1---基于XML文件的方式

spring注解

spring的配置介绍和bean的管理方式

3.Spring框架中的标签与配置文件分离

spring bean id和bean name的区别

Spring 配置使用 - 装配 Bean