Spring Bean Overriding 2.1.x во вложенном классе @Configuration @Создание компонента Bean завершается неудачно: «Bean с таким именем уже определен» - PullRequest
0 голосов
/ 11 октября 2018

обновление до spring-boot 2.1.0.M4 Переопределение bean-компонентов отключено по умолчанию.Если вы полагаетесь на переопределение, вам нужно установить в значение spring.main.allow-bean-definition-overriding значение true.

Но почему компонент Bean, определенный во внутреннем классе, также обрабатывается как дублированное определение компонента.Это ошибка?или у этого есть какое-то объяснение?

например:

@Configuration
public class BusinessLogicConfig {

    @Configuration
    class BusinessLogicSourceConfig {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("source");
        }
    }
}

отлично работает до spring-boot 2.0.x

, но при использовании, например, spring-boot 2.1.0.M4 выдает ошибку при запуске:

The bean 'businessLogic', defined in class path resource [com/example/di/bootconfigs/BusinessLogicConfig$BusinessLogicTier1Config.class], could not be registered.
A bean with that name has already been defined in URL [jar:file:/.../di/build/libs/di-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/com/example/di/businesslogic/BusinessLogic.class]
and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

Поскольку у меня явно есть только одно определение bean-компонента (определено только во внутреннем классе @Configuration), это кажется мне ошибкой.

Если вы спросите, почему я использую вложенный внутренний класс @Configuration:

У меня часто есть демонстрационный код, демонстрирующий поведение распределенной системы, в котором мне нужно более одного приложения для демонстрации.вещи.Поскольку я не хочу иметь несколько кодов приложений, я просто запускаю одно и то же приложение с разными профилями, а в профиль вводится «другая бизнес-логика», которую я хочу «сохранить вместе» в одном файле, например:

@Configuration
public class BusinessLogicConfig {

    @Value("${app.info.instance_index}")
    private String instanceIndex;

    @Profile({ "source" }) // unused fake BusinessLogic for pure sources
    @Configuration
    class BusinessLogicSourceConfig {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("source", instanceIndex);
        }
    }

    @Profile({ "sink" }) // unused fake BusinessLogic for pure sinks
    @Configuration
    class BusinessLogicSinkConfig {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("sink", instanceIndex);
        }
    }

    @Profile({ "tier1" })
    @Configuration
    class BusinessLogicTier1Config {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("tier1", instanceIndex);
        }
    }

    @Profile({ "tier2" })
    @Configuration
    class BusinessLogicTier2Config {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("tier2", instanceIndex);
        }
    }

    @Profile({ "tier3" })
    @Configuration
    class BusinessLogicTier3Config {
        @Bean
        public BusinessLogic businessLogic() {
            return new BusinessLogic("tier3", instanceIndex);
        }
    }

}

1 Ответ

0 голосов
/ 30 октября 2018

Оказывается, это не вложение класса @Configuration.Это сам класс BusinessLogic, то есть Бин с именем BusinessLogic, поскольку он является @Component.поэтому выше создается вторая версия Бина с именем BusinessLogic.

...