3

I have an interface which is defined in two places like that:

@Configuration
public class AppContext {
    @Bean
    public SomeInterface usageOne() {
        return new SameImpl();
    }

    @Bean
    public SomeInterface usageTwo() {
        return new SameImpl(someOtherConfig);
    }

    @Bean
    public Client clientOne(SomeInterface usageOne) {
        return new Client(usageOne);
    }

    @Bean
    public OtherClient clientTwo(SomeInterface usageTwo) {
        return new OtherClient(usageTwo);
    }
}

My client implementation classes do not have any annotations only required constructor. How to qualify the correct interface implementation usage in that case? I don't want to use @Primary as in my case it's semantically incorrect to name one of the usages as primary (they are in some sense equal). I need to pass the same interface with the same implementation class but configured differently for specific use cases of respected clients. I was thinking that naming the parameter by which I inject the implementation to the bean creation method is enough, but Spring complains with: required a single bean, but 2 were found. I don't understand how should I use the @Qualifier annotation.

I'm running with Spring Boot 2.0.4.RELEASE and respected beans and clients created in separate configuration classes so I cannot just call usageTwo() method when creating OtherClient like that: new OtherClient(usageTwo()); as this method is not available in clients configuration class.

Izbassar Tolegen
  • 1,990
  • 2
  • 20
  • 37

1 Answers1

4

As mentioned by @chrylis in the comments, you can simply add the @Qualifier annotation to the @Bean methods like this:

@Bean
public Client clientOne(@Qualifier("usageOne") SomeInterface usageOne) {
    return new Client(usageOne);
}

@Bean
public OtherClient clientTwo(@Qualifier("usageTwo") SomeInterface usageTwo) {
    return new OtherClient(usageTwo);
}

The value specified as value for the @Qualifier annotation is the respective bean's name. That is either the name of the corresponding @Bean method or the value of the annotation if used like this @Bean("usageThree").

dpr
  • 10,591
  • 3
  • 41
  • 71
  • Hi dpr, I don't think your reply "You will break the scope of the spring bean" is correct. When using the method directly the log do show "Creating shared instance of singleton bean ...beanName ". When you debug the objects where you use the bean, the instance of the bean is the same. – Rentius2407 Dec 14 '18 at 09:19
  • @Rentius2407, thanks for the feedback. You're actually right with static `@Bean` methods being an exception. See https://stackoverflow.com/questions/27990060/calling-a-bean-annotated-method-in-spring-java-configuration I reverted the respective part of my answer. – dpr Dec 14 '18 at 09:24