If you are trying to enter something with qualifications, where no bean exists for: like @Inject @Red IApple redApple; , then you get: NoSuchBeanDefinitionException .
This exception does not matter if you use:
- @Inject
- @Resource
- @Autowire
The reason is simple: Spring The first DI search identifies all candidates for auto-collection.
- if there is exactly one, he uses this candidate
- If there is no candidate, it raises a NoSuchBeanDefinitionException
- if there is more than one, he tries to identify a candidate for priming from denominations.
@see org.springframework.beans.factory.support.DefaultListableBeanFactory # doResolveDependency
line 785..809 (3.0.4.RELEASE)
So, what you need to do is postpone the drop (Apple) in the candiates set, but make sure that it is used only if there is no other candidate. Since you cannot mark a bean as a fallback or less importend, you need to mark the normal bean as more important: @primary .
So the (proven) solution will annotate
- Black and red apple with @Black and @Red and with @Primary.
- The default backup is Apple (Apple1) with @Red and @Black, but without @Primary.
Example:
@Component @Red @Black public class Apple1 implements IApple {} //fall back @Component @Black @Primary public class Apple2 implements IApple {} @Component public class AppleEater { @Inject @Black IApple blackApple; // -> Apple2 @Inject @Red IApple redApple; // -> Apple1 }
Possible improvement: if you do not like to add all annotations (@Black, @Red, @AllOtherStangeColors) to your bean return, you can try to implement your own AutowireCandiateResolver so that it adds a bean drop to all denominations of the required type (Apple) @ see Reference documentation: 3.9.4 CustomAutowireConfigurer
Ralph source share