Подтвердить что ты не робот

Аннотирование bean имя конфликтует с существующим, несовместимым bean def

У меня проблема с некоторыми определениями Spring bean. У меня есть несколько xml файлов контекста, которые загружаются моим методом main(), и оба они содержат почти исключительно тег. Когда мой основной метод запускается, я получаю эту ошибку от Spring:

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'converterDAO' for bean class [my.package.InMemoryConverterDaoImpl] conflicts with existing, non-compatible bean definition of same name and class [my.other.package.StaticConverterDAOImpl]

Оба класса DAO аннотируются следующим образом:

@Repository("converterDAO")
public class StaticConverterDAOImpl implements ConverterDAO {
...
}

В памяти dao также есть аннотация @Repository ( "converterDAO" ). Дао ссылается на другие классы следующим образом:

...
private @Autowired @Qualifier("converterDAO") ConverterDAO converterDAO;
...

Я хочу, чтобы один DAO переопределял определение другого, что, как я всегда понимал, это была одна из основных причин использования основы DI. Я делал это с определениями xml в течение многих лет и никогда не испытывал никаких проблем. Но не так с помощью компонентного сканирования и аннотированных определений bean? И что означает Spring, когда говорится, что они не "совместимы"? Они реализуют один и тот же интерфейс, и они автоматически добавляются в поля этого типа интерфейса. Почему они не совместимы?

Может ли кто-нибудь предоставить мне способ для одного аннотированного, компонентного сканирования bean переопределить другой?

-Mike

4b9b3361

Ответ 1

В XML файле существует последовательность объявлений, и вы можете переопределить предыдущее определение с более новым. Когда вы используете аннотации, нет понятия до или после. Все beans находятся на одном уровне. Вы определили два beans с тем же именем, а Spring не знает, какой из них выбрать.

Дайте им другое имя (например, staticConverterDAO, inMemoryConverterDAO), создайте псевдоним в XML файле Spring (например, ConverterDAO) и используйте этот псевдоним при инъекции конвертера:

@Autowired @Qualifier("theConverterDAO")

Ответ 2

У меня была аналогичная проблема с двумя библиотеками jar (app1 и app2) в одном проекте. определено в приложении 1 и расширено в app2 и bean переопределено с тем же именем.

В приложении 1:

package com.foo.app1.pkg1;

@Component("BeanName")
public class Class1 { ... }

В app2:

package com.foo.app2.pkg2;

@Component("BeanName")
public class Class2 extends Class1 { ... }

Это вызывает исключение ConflictingBeanDefinitionException при загрузке applicationContext из-за того же имени компонента bean.

Чтобы решить эту проблему, в файле конфигурации Spring applicationContext.xml:

<context:component-scan base-package="com.foo.app2.pkg2"/>
<context:component-scan base-package="com.foo.app1.pkg1">
    <context:exclude-filter type="assignable" expression="com.foo.app1.pkg1.Class1"/>
</context:component-scan>

Таким образом, Class1 исключается для автоматического сканирования компонентов и назначается bean, избегая конфликта имен.

Ответ 3

У меня была аналогичная проблема с Spring 4.x с помощью @RestController. У двух разных пакетов был класс с тем же именем...

package com.x.catalog

@RestController
public class TextureController {
...

package com.x.cms
@RestController
public class TextureController {
...

Исправить было легко...

package com.x.catalog

@RestController("CatalogTextureController")
public class TextureController {
...

package com.x.cms
@RestController("CMSTextureController")
public class TextureController {
...

Похоже, проблема заключается в том, что аннотация становится автоматически и принимает имя класса по умолчанию. Предоставление им явного имени в аннотации @RestController позволяет сохранить имена классов.

Ответ 4

У меня была похожая проблема, и это было потому, что один из моих bean-компонентов был недавно перемещен в другой каталог. Мне нужно было выполнить "чистую сборку", удалив каталог build/classes/java и проблема исчезла. (В сообщении об ошибке два разных пути к файлам конфликтовали друг с другом, хотя я знал, что один не должен больше существовать.)

Ответ 5

Сценарий:

Я работаю над многомодульным проектом Gradle.

Модули это:

- core, 
- service,
- geo,
- report,
- util and
- some other modules.

Итак, в первую очередь мы подготовили Компонент [ locationRecommendHttpClientBuilder ] в геомодуле.

Java-код:

import org.springframework.stereotype.Component

@Component("locationRecommendHttpClientBuilder")
class LocationRecommendHttpClientBuilder extends PanaromaHttpClientBuilder {
    @Override
    PanaromaHttpClient buildFromConfiguration() {
        this.setURL(PanaromaConf.getInstance().getString("locationrecommend.url"))
        this.setMethod(PanaromaConf.getInstance().getString("locationrecommend.method"))
        this.setProxyHost(PanaromaConf.getInstance().getString("locationrecommend.proxy.host"))
        this.setProxyPort(PanaromaConf.getInstance().getInt("locationrecommend.proxy.port", 0))
        return super.build()
    }
}

Приложение-context.xml

<bean id="locationRecommendHttpClient"
      class="au.co.google.panaroma.platform.logic.impl.PanaromaHttpClient"
      scope="singleton" factory-bean="locationRecommendHttpClientBuilder"
      factory-method="buildFromConfiguration" />

Затем решено добавить этот компонент в основной модуль.

У одного инженера был предыдущий код для геомодуля, а затем он взял последний модуль ядра, но забыл взять последний геомодуль.

Так что компонент [ locationRecommendHttpClientBuilder ] дважды в своем проекте, и он получил следующую ошибку.

Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'LocationRecommendHttpClientBuilder' for bean class [au.co.google.app.locationrecommendation.builder.LocationRecommendHttpClientBuilder] conflicts with existing, non-compatible bean definition of same name and class [au.co.google.panaroma.platform.logic.impl.locationRecommendHttpClientBuilder]

Процедура решения:

После удаления компонента из геомодуля компонент [ locationRecommendHttpClientBuilder ] доступен только в основном модуле. Так что нет конфликтной ситуации. Проблема решена этим способом.

Ответ 6

У меня тоже была похожая проблема. Я построил проект снова, и проблема была решена.

Причина в том, что в файле уже определены последовательности для имен компонентов, указанных в аннотации. Когда мы вносим изменения в это имя бина и пытаемся запустить приложение, Spring не может определить, какое из них выбрать. Вот почему он показывает эту ошибку.

В моем случае я удалил предыдущий класс компонента из проекта и добавил то же имя компонента в новый класс компонента. Таким образом, Spring имеет предыдущее определение для удаленного класса bean-компонента в файле, и это конфликтует с вновь добавленным классом во время компиляции. Поэтому, если вы выполните 'build clean', предыдущие определения классов bean-компонентов будут удалены, и компиляция будет успешной.

Ответ 7

Я столкнулся с этой проблемой, когда импортировал два проекта в рабочую область. Он каким-то образом создал другой jar файл, поэтому мы можем удалить jar файлы и файлы классов и собрать проект заново, чтобы получить правильные зависимости.

Ответ 8

Иногда проблема возникает, если вы переместили свои классы, и это относится к старым классам, даже если они не существуют.

В этом случае просто сделайте это:

mvn eclipse:clean

mvn eclipse:eclipse

Это хорошо сработало для меня.