Defining the same Spring bean twice with same name

巧了我就是萌 提交于 2019-11-30 06:36:43

问题


Is having two definition for a bean (with same name and class) valid in Spring IOC ?

I am having two bean definition files included in web.xml. See the sample below.

applicationContext-beans1.xml

<bean name="myWao"
    class="com.beans.myBean">       
</bean> 

applicationContext-beans2.xml

<bean name="myWao"
    class="com.beans.myBean">       
</bean> 

I am not facing any issue till now. But, will this possibly impact in the real environment which will be multi threaded and clustered ?

Note: Both the XMLs are loaded as I am able to use the other beans defined(only once) in both the XMLs


回答1:


It's valid, but you'll find that one bean is overridden by the other. You'll see this in the logs as

Overriding bean definition for...

This behaviour allows you to override previously supplied bean definitions. It affects the static assembly of your app, and doesn't relate to threading/clustering as suggested in your question.

Note that the DefaultListableBeanFactory allows you to configure this behaviour via setAllowBeanDefinitionOverriding()




回答2:


This is valid and useful especially when you try to change the implementation of a third party bean (I mean, where you are not allowed to change the implementation of a bean) and Where you need to provide/configure some extra (merge) properties for the bean.

The overriding of the bean depends upon the order of the xmls you provide to build the ApplicationContext through web.xml or stand-alone. The latest bean definition will win the game.




回答3:


I know it is very very late to reply, But sill want to add something...

It valid as long as you are defining two bean definitions with same id of same bean on two different spring configuration files. And you are importing one configuration file into another (kind of merging), does not matter how you importing (kind of merging). The later one or the last one bean definition will be override by the first one(s).

package com.demo.bean;
public class TestBean {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

e.g # 1

spring-config1.xml

<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="INSIDE_SPRING_CONFIG_1"></property>
</bean>

spring-config2.xml

<import resource="spring-config1.xml"/><
<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="INSIDE_SPRING_CONFIG_1"></property>
</bean>

e.g # 2

spring-config1.xml

<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="INSIDE_SPRING_CONFIG_1"></property>
</bean>

spring-config1.xml

<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="INSIDE_SPRING_CONFIG_1"></property>
</bean>

web.xml

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring-config1.xml,
        /WEB-INF/spring-config2.xml
    </param-value>
</context-param>

But if you are defining the two bean definitions with same bean id of same bean in same file you will find spring application start up failed. Spring would not let you define multiple bean definitions of same bean with same name in the same spring configuration file.

e.g # 3 spring-config3.xml

<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="CONFIG_VALUE_1"></property>
</bean>
<bean id="testbean" class="com.demo.TestBean">
    <property name="message"    value="CONFIG_VALUE_2"></property>
</bean>

Error :

ERROR ContextLoader:331 - Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'testbean' is already used in this <bean> element
Offending resource:  resource [/spring-config3.xml]

    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:70)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:85)
    at org.springframework.beans.factory.parsing.ReaderContext.error(ReaderContext.java:80)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.error(BeanDefinitionParserDelegate.java:316)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.checkNameUniqueness(BeanDefinitionParserDelegate.java:525)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:471)
    at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseBeanDefinitionElement(BeanDefinitionParserDelegate.java:443)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(DefaultBeanDefinitionDocumentReader.java:314)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseDefaultElement(DefaultBeanDefinitionDocumentReader.java:205)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:184)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:141)
    at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:110)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:508)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:391)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:335)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:303)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:180)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:216)
    at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:187)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:125)
    at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:94)
    at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
    at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:540)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:454)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4716)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5178)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)


来源:https://stackoverflow.com/questions/10993181/defining-the-same-spring-bean-twice-with-same-name

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!