Here is my question:I have a base interface and two implementation class.
And a Service class has a dependencies on the base interface, the code is like this:
@Component public interface BaseInterface {}
@Component public class ClazzImplA implements BaseInterface{}
@Component public class ClazzImplB implements BaseInterface{}
And the configuration is like this :
@Configuration public class SpringConfig { @Bean public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean public BaseInterface clazzImplB(){ return new ClazzImplB(); } }
The service class has dependencies on the base interface will decide to autowire which Implementation by some business logic.And the code is like this:
@Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired private BaseInterface baseInterface; private AutowiredClazz(BaseInterface baseInterface){ this.baseInterface = baseInterface; } }
And the IDEA throws a exception:Could not autowire.There is more than one bean of BaseInterface
type.
Although it can be solved by using @Qualifier,but in this situation I can't choose the dependencies class.
@Autowired @Qualifier("clazzImplA") private BaseInterface baseInterface;
I tried to read the spring document and it provide a Constructor-based dependency injection
but I'm still confused by the problem.
can anyone help me ?
When a bean implementation exists both in the production and test codes, IntelliJ will mark @Autowired instances of this bean as "cannot autowire, more than one bean...". This is of course incorrect, as the test implementation will never be deployed in a production environment.
When there is more than one matching bean, the ambiguity doesn't allow Spring to autowire the properties, constructor arguments or method parameters. Let us understand this with the help of an example below.
The @Qualifier annotation is used to resolve the autowiring conflict, when there are multiple beans of same type. The @Qualifier annotation can be used on any class annotated with @Component or on methods annotated with @Bean . This annotation can also be applied on constructor arguments or method parameters.
Another autowire mode autodetect has been deprecated. Docs says that the “autodetect” option provided too much “magic” and a more explicit declaration is preferred. The default autowire mode in XML configuration is no . The default autowire mode in java configuration is byType .
Spring is confused between the 2 beans you have declared in you configuration class so you can use @Qualifier
annotation along with @Autowired
to remove the confusion by specifying which exact bean will be wired, apply these modifications on your configuration class
@Configuration public class SpringConfig { @Bean(name="clazzImplA") public BaseInterface clazzImplA(){ return new ClazzImplA(); } @Bean(name="clazzImplB") public BaseInterface clazzImplB(){ return new ClazzImplB(); } }
then at @autowired
annotation
@Service @SpringApplicationConfiguration(SpringConfig.class) public class AutowiredClazz { @Autowired @Qualifier("the name of the desired bean") private BaseInterface baseInterface; private AutowiredClazz(BaseInterface baseInterface){ this.baseInterface = baseInterface; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With