Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

spring Bean Overriding 2.1.x in nested class @Configuration @Bean creation fails with 'A bean with that name has already been defined' [SPR-17365] #21898

Open
spring-projects-issues opened this issue Oct 11, 2018 · 1 comment
Labels
in: core status: waiting-for-triage

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Oct 11, 2018

Dirk Hoffmann opened SPR-17365 and commented

upgrading to spring-boot 2.1.0.M4 Bean overriding has been disabled by default.
If you are relying on overriding, you will need to set spring.main.allow-bean-definition-overriding to true.

But why is a Bean defined in an inner class also treated like a duplicate bean definition. Is this a bug? or has this some explanation?

e.g.:

 

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

works fine up to spring-boot 2.0.x

but when using e.g. spring-boot 2.1.0.M4 it gives me an error on startup:

 

The bean 'businessLogic', defined in class path resource [com/example/di/bootconfigs/BusinessLogicConfig$BusinessLogicSourceConfig.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
 

As I clearly only have a single definition of the bean (only defined in an inner @Configuration class) this seems like a bug to me.

If you ask why I am using a nested inner @Configuration class:

I often have demo code, demonstrating distributed system behavior in which I need more than one app to demonstrate things. As I don't want to have multiple App code, I just start the same App with different profiles and the profile is injecting "different business logic" which I want to "keep together" in one file, like:

 

@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);
        }
    }
     
 }
 

source code at: git@gitlab.com:hoffi_scratch/di.git

 


Affects: 5.1 GA

Reference URL: https://gitlab.com/hoffi_scratch/di

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Oct 11, 2018

Andy Wilkinson commented

You do have defined two beans named businessLogic. You have a @Bean method called businessLogic. The method name is used as the bean's name so the bean's name is businessLogic. Your BusinessLogic class is annotated with @Component and is being picked up by component scanning. The default bean name for a class named BusinessLogic is businessLogic so you end up with two beans with the same name, hence the attempted override.

 

@spring-projects-issues spring-projects-issues added type: bug status: waiting-for-triage in: core and removed type: bug labels Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core status: waiting-for-triage
Projects
None yet
Development

No branches or pull requests

1 participant