春天的压倒一切的豆子

gau*_*rav 35 spring

我们可以为XML中提到的相同bean id重复名称吗?如果没有,那么我们如何在Spring中覆盖bean呢?

ska*_*man 62

任何给定的Spring上下文对于任何给定的id或名称只能有一个bean.对于XML id属性,这由架构验证强制执行.在name属性的情况下,这是由Spring的逻辑强制执行的.

但是,如果上下文是由两个不同的XML描述符文件构造的,并且id两个文件都使用了一个上下文,那么一个文件将"覆盖"另一个文件.确切的行为取决于文件在上下文加载时的顺序.

所以虽然有可能,但不建议这样做.它容易出错并且很脆弱,如果你更改一个而不是另一个的ID,你将无法获得Spring的帮助.

  • 如果它们处于同一层次结构级别,则存在风险,但可以使用“配置文件”(请参阅​​我的答案)来更好地控制它。 (2认同)
  • 有没有办法指示Spring遇到任何具有相同id的bean(即强调不允许覆盖)时抛出错误?这是针对`ServletContextHandler`的`contextConfigLocation`属性. (2认同)

lbo*_*oix 12

我将补充说,如果你的需要只是覆盖你的bean使用的属性,id方法也像skaffman解释的那样:

在您的第一个名为XML的配置文件中:

   <bean id="myBeanId" class="com.blabla">
       <property name="myList" ref="myList"/>
   </bean>

   <util:list id="myList">
       <value>3</value>
       <value>4</value>
   </util:list>
Run Code Online (Sandbox Code Playgroud)

在您的第二个称为XML配置文件中:

   <util:list id="myList">
       <value>6</value>
   </util:list>
Run Code Online (Sandbox Code Playgroud)

然后你的bean"myBeanId"将使用一个元素的"myList"属性进行实例化,该属性为6.


Den*_*hev 8

官方春季手册的一个例子:

<bean id="inheritedTestBean" abstract="true"
    class="org.springframework.beans.TestBean">
  <property name="name" value="parent"/>
  <property name="age" value="1"/>
</bean>

<bean id="inheritsWithDifferentClass"
      class="org.springframework.beans.DerivedTestBean"
      parent="inheritedTestBean" init-method="initialize">
  <property name="name" value="override"/>
  <!-- the age property value of 1 will be inherited from  parent -->
</bean>
Run Code Online (Sandbox Code Playgroud)

那是你在找什么?


Roe*_*rel 8

不确定这是否正是您所需要的,但我们使用配置文件来定义我们正在运行的环境以及每个环境的特定bean,所以它是这样的:

<bean name="myBean" class="myClass">
    <constructor-arg name="name" value="originalValue" />
</bean>
<beans profile="DEV, default">
     <!-- Specific DEV configurations, also default if no profile defined -->
    <bean name="myBean" class="myClass">
        <constructor-arg name="name" value="overrideValue" />
    </bean>
</beans>
<beans profile="CI, UAT">
     <!-- Specific CI / UAT configurations -->
</beans>
<beans profile="PROD">
     <!-- Specific PROD configurations -->
</beans>
Run Code Online (Sandbox Code Playgroud)

所以在这种情况下,如果我没有定义一个配置文件或者我将它定义为"DEV",myBean将为它的name参数获得"overrideValue".但是如果我将配置文件设置为"CI","UAT"或"PROD",它将获得"originalValue"作为值.


Dmi*_*try 5

从 Spring 3.0 开始,您可以使用@Primary注释。根据文档:

指示当多个候选者有资格自动装配单值依赖项时,应优先考虑某个 bean。如果候选者中恰好存在一个“主要”bean,则它将是自动装配的值。该注释在语义上等同于 Spring XML 中元素的主要属性。

你应该在 Bean 定义中使用它,如下所示:

@Bean
@Primary
public ExampleBean exampleBean(@Autowired EntityManager em) {
    return new ExampleBeanImpl(em);
}
Run Code Online (Sandbox Code Playgroud)

或者像这样:

@Primary
@Service
public class ExampleService implements BaseServive {
}
Run Code Online (Sandbox Code Playgroud)