如果你尝试注入一些不存在 bean 的符合条件的东西,
@Inject @Red IApple redApple;
那么你会得到一个:NoSuchBeanDefinitionException
。
无论您是否使用,都会发生此异常:
原因很简单:Spring DI 首先搜索确定所有自动装配候选者。
- 如果正好有一个,它使用这个候选人
- 如果没有候选人,它会引发 NoSuchBeanDefinitionException
- 如果有多个,它会尝试从候选中确定初级候选。
@参见 org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
第 785..809 行(3.0.4.RELEASE)
因此,您需要做的是将后备(Apple)之一放入候选集,但请确保仅在没有其他候选者时使用它。因为没有办法将 bean 标记为 fall back 或 less importend,所以您需要将普通 bean 标记为更重要@primary
:
所以(证明的)解决方案将是注释
- 带有@Black 和@Red 以及@Primary 的黑色和红色苹果。
- 默认后备 Apple (Apple1),带有 @Red 和 @Black,但没有 @Primary。
例子:
@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
}
可能的改进:如果您不喜欢将所有注释(@Black、@Red、@AllOtherStangeColors)添加到您的后备 bean,您可以尝试实现您自己的AutowireCandiateResolver
,以便将后备 bean 添加到所有候选列表所需类型(Apple)
@see 参考文档:3.9.4 CustomAutowireConfigurer