Beanの2つの定義(同じ名前とクラス)がSpringで有効ですかIOC?
Web.xmlに2つのBean定義ファイルが含まれています。以下のサンプルを参照してください。
applicationContext-beans1.xml
<bean name="myWao"
class="com.beans.myBean">
</bean>
applicationContext-beans2.xml
<bean name="myWao"
class="com.beans.myBean">
</bean>
今まで問題はありません。しかし、これはマルチスレッド化されてクラスター化される実際の環境に影響を与える可能性がありますか?
注:両方のXMLで定義されている他のBeanを(一度だけ)使用できるため、両方のXMLがロードされます
それは有効ですが、1つのBeanが他のBeanによってオーバーライドされることがわかります。これはログに次のように表示されます
Overriding bean definition for...
この動作により、以前に提供されたBean定義をオーバーライドできます。これはアプリの静的アセンブリに影響し、質問で提案されているスレッド化/クラスタリングには関係ありません。
DefaultListableBeanFactory
では、この動作を setAllowBeanDefinitionOverriding() で設定できることに注意してください
これは、サードパーティBeanの実装を変更しようとする場合(つまり、Beanの実装を変更することが許可されていない場合)、および追加の(マージ)プロパティを提供/構成する必要がある場合に特に有効で便利です。豆。
Beanのオーバーライドは、web.xmlまたはスタンドアロンでApplicationContext
を構築するために提供するxmlの順序に依存します。最新のBean定義がゲームに勝ちます。
返信が非常に遅いのはわかっていますが、何かを追加したいのですが...
2つの異なるSpring構成ファイルで同じBeanの同じIDを持つ2つのBean定義を定義している限り、これは有効です。そして、1つの構成ファイルを別の構成ファイルにインポートしています(マージの種類)。どのようにインポートするか(マージの種類)は関係ありません。後のBean定義または最後のBean定義は、最初の定義によってオーバーライドされます。
package com.demo.bean;
public class TestBean {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
例:#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>
例#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>
ただし、同じファイル内で同じBeanの同じBean IDを持つ2つのBean定義を定義している場合、Springアプリケーションの起動が失敗することがわかります。 Springでは、同じSpring構成ファイルで同じ名前の同じBeanの複数のBean定義を定義できません。
例#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 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)
Spring Bootバージョン2.1以降では、デフォルトで無効になっています。 ( リンク )
Beanのオーバーライド:Beanのオーバーライドは、Beanが誤ってオーバーライドされるのを防ぐために、デフォルトで無効になっています。オーバーライドに依存している場合は、
spring.main.allow-bean-definition-overriding
をtrue
に設定する必要があります。