When one @Configuration class have two bean factory methods with same name (but different arguments), then Spring creates both beans using only one of those factory methods.

Example:

@Configuration
public class Config {

    @Bean
    public String foo() {
        return "foo";
    }

    @Qualifier("printer1")
    @Bean(name = "printer1")
    public Printer printer1() {
        return new Printer1();
    }

    // This factory method overrides the method with the same name for both beans.
    // The result is context with 2 beans, each has own name and qualifier, but both created with
    // the same factory method (this method). Other factory method (printer1()) is ignored.
    // So, basically there are 2 Printer2 instances in the context.
    @Qualifier("printer2")
    @Bean(name = "printer2")
    public Printer printer1/* Here is the bug */(String foo) {
        return new Printer2();
    }


    public interface Printer {
        void print();
    }

    public static class Printer1 implements Printer {
        @Override
        public void print() {
            System.out.println("I'm Printer 1");
        }
    }

    public static class Printer2 implements Printer {
        @Override
        public void print() {
            System.out.println("I'm Printer 2");
        }
    }

}
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Bean
    ApplicationRunner applicationRunner(List<Config.Printer> printers) {
        return args -> printers.forEach(Config.Printer::print);
    }

}

This prints:

I'm Printer 2
I'm Printer 2

If you try to inject qualified printer1 bean it also will print I'm Printer 2. So, basically the context will have 2 beans, each with own qualifier etc, but both will be created using second factory method.

The solution is to rename first or second factory method to any other name to be different from name of the other method (e.g. printer5). Splitting @Configuration to 2 configurations also works.

As @mdeinum mentioned here the problem can be with ConfigurationClassBeanDefinitionReader.

Comment From: jnizet

This looks like a duplicate of #25263

Comment From: jhoeller

This looks like a duplicate of the recently fixed #25263 indeed. Please try the latest 5.3.0.BUILD-SNAPSHOT if you have a chance.

Generally speaking, please try to avoid using the same factory method names for different bean names. This is brittle since at a fundamental level, such same-named methods are overloaded methods in Java and should be treated as such.

Comment From: xak2000

Thanks! I understand that I should try to avoid same-named methods, and that it's a little contrived example. But still think that Spring should not behave like that. If it would print an error, it is totally acceptable. But silently use wrong factory method is not, IMHO. Can be source of strange bugs in end-user code.

I'll try the SNAPSHOT version, thanks!
The version I tested was 5.2.8.RELEASE.

Comment From: xak2000

5.3.0-SNAPSHOT version fixes the issue. Feel free to close as duplicate then.

Comment From: jhoeller

Thanks for trying the snapshot so quickly! I forgot to mention that this will also be in 5.2.9 and is therefore also available in 5.2.9.BUILD-SNAPSHOT already.

Closing as a duplicate of #25263 then.