В Spring Boot 2.1 было внесено изменение, чтобы отключить переопределение bean-компонентов по умолчанию. Это было сделано, чтобы упростить идентификацию и исправление случайного переопределения компонента. Случайное переопределение - то, что, кажется, происходит здесь.
AppErrorController
помечен @Controller
, что означает @Component
, и он, похоже, находится в пакете, который покрывается компонентным сканированием. Когда при сканировании компонента встречается AppErrorController
, он определяет компонент с именем appErrorController
.
DevApplicationConfig
затем обрабатывается. Он содержит метод @Bean
, который определяет компонент с именем appErrorController
:
@Bean
public AppErrorController appErrorController(){
return new AppErrorController(errorAttributes);
}
В Spring Boot 2.0 и более ранних версиях это приведет к тому, что компонент AppErrorController
, определенный посредством сканирования компонентов, будет переопределен компонентом, определенным в DevApplicationConfig
. Если вы внимательно посмотрите журналы при запуске приложения с Spring Boot 2.0.x, вы должны увидеть, что для переопределенного компонента было зарегистрировано информационное сообщение. В Spring Boot 2.1 это приводит к сбою из-за того, что переопределение бина отключено по умолчанию.
Чтобы устранить проблему, удалите метод appErrorController
@Bean
из DevApplicationConfig
. Это позволяет использовать определение, сгенерированное путем сканирования компонентов. Я бы порекомендовал сделать то же самое изменение в Spring Boot 2.0 и более ранних приложениях. Удаление ненужного переопределения делает запуск приложения немного более эффективным и позволяет избежать загромождения журналов вашего приложения информационными сообщениями о переопределении bean-компонентов.
Если вам нужно переопределить bean-компонент в Spring Boot 2.1, вы можете восстановить поведение 2.0, установив свойство:
spring.main.allow-bean-definition-overriding=true
Я бы рекомендовал делать это только в том случае, если вы находитесь в необычной ситуации, когда переопределение является преднамеренным, и нет простого способа изменить конфигурацию, чтобы она не возникала.