Можем ли мы иметь повторяющиеся имена для того же идентификатора bean, который упоминается в XML? Если нет, то как мы переопределяем bean в Spring?
Spring переопределение bean
Ответ 1
Любой заданный контекст Spring может иметь только один bean для любого имени или имени. В случае атрибута XML id
это выполняется с помощью проверки схемы. В случае атрибута name
это выполняется логикой Spring.
Однако, если контекст построен из двух разных файлов дескриптора XML, а id
используется обоими файлами, тогда один будет "переопределять" другой. Точное поведение зависит от упорядочения файлов, когда они загружаются контекстом.
Поэтому, когда это возможно, это не рекомендуется. Он подвержен ошибкам и хрупким, и вы не получите никакой помощи от Spring, если вы измените идентификатор одного, а не другого.
Ответ 2
Я добавлю, что если вам нужно только переопределить свойство, используемое вашим bean, подход id работает так же, как скаффман объяснил:
В первом файле конфигурации 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>
В вашем втором файле конфигурации XML:
<util:list id="myList">
<value>6</value>
</util:list>
Затем ваш bean "myBeanId" будет создан с использованием свойства "myList" одного элемента, который равен 6.
Ответ 3
Пример из официального весеннего руководства:
<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>
Это то, что вы искали? Обновленная ссылка
Ответ 4
Не уверен, что это именно то, что вам нужно, но мы используем профили, чтобы определить среду, в которой мы работаем, и конкретный 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>
Итак, в этом случае, если я не определяю профиль, или если я определяю его как "DEV", myBean получит "overrideValue" для его аргумента name. Но если я установил профиль в "CI", "UAT" или "PROD", он получит значение "originalValue".
Ответ 5
Альтернативный подход к переопределению bean осуществляется через псевдонимы. Эта статья статьи в блоге объясняет этот подход.
Ответ 6
Другим хорошим подходом, который не упоминается в других сообщениях, является использование PropertyOverrideConfigurer в случае, если вы просто хотите переопределить свойства некоторых beans.
Например, если вы хотите переопределить источник данных для тестирования (т.е. использовать базу данных в памяти) в другой конфигурации xml, вам просто нужно использовать <context:property-override ..."/>
в новой конфигурации и файл .properties
, содержащий значения ключа формат beanName.property=newvalue
, перекрывающий основные реквизиты.
приложения mainConfig.xml:
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
p:driverClassName="org.postgresql.Driver"
p:url="jdbc:postgresql://localhost:5432/MyAppDB"
p:username="myusername"
p:password="mypassword"
destroy-method="close" />
приложения testConfig.xml:
<import resource="classpath:path/to/file/application-mainConfig.xml"/>
<!-- override bean props -->
<context:property-override location="classpath:path/to/file/beanOverride.properties"/>
beanOverride.properties:
dataSource.driverClassName=org.h2.Driver
dataSource.url=jdbc:h2:mem:MyTestDB
Ответ 7
Можно ли объявить тот же самый bean id в другом xml для другой ссылки e.x.
сервлетов-Initialize.xml
<bean id="inheritedTestBean" class="org.springframework.beans.TestBean">
<property name="name" value="parent"/>
<property name="age" value="1"/>
</bean>
Другие xml (Document.xml)
<bean id="inheritedTestBean" class="org.springframework.beans.Document">
<property name="name" value="document"/>
<property name="age" value="1"/>
</bean>