Переопределение bean-компонента DataSource в весенней загрузке 2.1

Я обновился до версии spring boot 2.1, и при запуске приложения возникла странная исключительная ситуация.

The bean 'dataSource', defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class] and overriding is disabled.

Полное сообщение об ошибке:

[o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext] Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'dataSource' defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]: Cannot register bean definition [Root bean: class [org.springframework.aop.scope.ScopedProxyFactoryBean]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in BeanDefinition defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] for bean 'dataSource': There is already [Root bean: class [null]; scope=refresh; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=false; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari; factoryMethodName=dataSource; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/jdbc/DataSourceConfiguration$Hikari.class]] bound.

Bean-компоненты не должны быть переопределены в соответствии с нашей политикой, и они отключены с помощью:

spring.main.allow-bean-definition-overriding=false

В моем коде приложения нет конфигурации источника данных. Единственный вариант, который вызывает эту ошибку, - @EnableAutoConfiguration, и в свойствах моего приложения я установил тип источника данных:

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

Загрузочное приложение инициализируется с помощью

@SpringBootApplication
@EnableAutoConfiguration
public class MyApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        new MyApplication()
            .configure(new SpringApplicationBuilder(MyApplication.class))
            .run(args);
    }
}

Также существует класс конфигурации, который импортирует различные другие конфигурации:

@Configuration
@ImportResource(locations = {
    "classpath*:conf/spring/*.xml",
    "classpath*:conf/spring/core/*.xml",
    "classpath*:conf/spring/plugin/**/*.xml"
})
@EnableAsync
@EnableRetry
@EnableCaching
@EnableBatchProcessing
@EnableCircuitBreaker
public class AppConfig {
    ...
}

Кто-нибудь знает, что может вызвать эту проблему и где искать?

Этого не было до Spring Boot 2.1 (т.е. 2.0.5).

Вам не нужно устанавливать тип источника данных (по умолчанию - hikari), по умолчанию - spring.main.allow-bean-definition-overriding=false. Не могли бы вы добавить полную трассировку стека и добавить свой аннотированный класс @SpringBootApplication?

M. Deinum 01.11.2018 16:54

@ M.Deinum Я обновил вопрос с полной информацией об ошибках и классах конфигурации приложения.

Mariusz Miesiak 01.11.2018 17:05

Удалите @EnableAutoConfiguration, который уже подразумевается @SpringBootApplication. Также ваша установка немного странная, зачем расширять SpringBootServletInitializer, не применяя правильные методы? и то, что вы делаете в своем основном методе, также не является стандартным, просто используйте SpringApplication.run(MyuApplication.class, args); вместо того, что у вас есть сейчас.

M. Deinum 01.11.2018 17:08

@ M.Deinum это та же ошибка после применения всех этих изменений.

Mariusz Miesiak 01.11.2018 17:17

Загружается довольно много XML-файлов, разве это не вызывает еще один импорт уже существующего класса конфигурации? Например, слишком широкое сканирование компонентов?

M. Deinum 01.11.2018 17:18

Почему-то кажется, что автоконфигурация источника данных обрабатывается дважды. Как предполагает @ M.Deinum, это могло быть связано, помимо прочего, с слишком широким сканированием компонентов. Невозможно сказать наверняка, не ознакомившись со всеми соответствующими частями вашего приложения. Можете ли вы предоставить минимальный, полный и проверяемый пример?

Andy Wilkinson 01.11.2018 19:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
29
6
44 511
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

Сегодня я столкнулся с аналогичной проблемой, и мне помогла следующая проблема с весенней облачной конфигурацией: Проблема 1142.

Мы использовали Spring Cloud Config, который пока не совместим со Spring Boot 2.1.0. Линия выпуска Spring Cloud по Гринвичу будет совместима с Spring Boot 2.1.0.

Ваша аннотация @EnableCircuitBreaker наводит меня на мысль, что вы также можете использовать версию Spring Cloud, несовместимую с выпуском Spring Boot 2.1.0.

В моем случае у меня был @EnableGlobalMethodSecurity дважды в моем проекте. Но это было похоже на stackoverflow.com/questions/54059222/…

Andrei Sfat 12.05.2020 08:23

org.springframework.cloud:spring-cloud-context:2.0.2.RELEASE

Обновить вызывает эту проблему при обновлении HikariDatasource в

возможное исправление

spring.cloud.refresh.enabled = false

Для Spring Boot 2+ вы можете исключить автоконфигурацию

@SpringBootApplication(exclude = ElasticsearchDataAutoConfiguration.class)
     public class YourApplication {
 ... }

Я столкнулся с подобной проблемой, и она очень общая (иногда дублируются аннотации, иногда дублируются beans). В случае, если вы дублировали аннотацию, например @EnableJpaRepository, сообщение об ошибке вообще не упоминает эту аннотацию. Лучший способ найти причину проблемы:

Открытый класс DefaultListableBeanFactory Должен быть такой код:

BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

Поместите точку останова в строку с throw new. Тогда existingDefinition.source.className указывает на конфигурацию, которая уже зарегистрирована, и вот в чем проблема. Когда вы проверяете beanDefinition.source.className, вы сравниваете оба класса и обнаруживаете дублированный код или аннотацию, просто удалите / исправьте их.

Добавление следующего свойства в application.properties решит проблему.

spring.main.allow-bean-definition-overriding = истина

Кроме того, может потребоваться добавить еще одно свойство для решения другой упомянутой проблемы: https://github.com/openzipkin/zipkin/issues/2043

management.metrics.web.server.auto-time-requests = false

У меня возникла эта проблема, когда я пытаюсь настроить Redis в своем проекте, и, наконец, я решил ее, используя:

@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})

Я использую SpringBoot 2.4.2

У меня была та же проблема, и я искал лучшее и более общее решение, и я нашел следующее:

1- проверьте здесь, чтобы узнать, какие версии Spring Cloud совместимы с вашей версией загрузки весеннее облако

2- после этого перейдите сюда, чтобы выбрать именно ту версию, которая вам нравится весенние облачные релизы

Эти шаги решили проблему для меня без каких-либо других шагов конфигурации. Но для вас это может быть другая несовместимая зависимость. Это не обязательно должно быть весеннее облако.

Другие вопросы по теме