关于Spring DI中的限定符的问题

时间:2011-03-16 10:32:41

标签: java spring dependency-injection jsr330

通常,合格的组件将使用相同的限定符注入带注释的字段:

@Component        class Apple1 implements IApple {}
@Component @Black class Apple2 implements IApple {}

class User {
    @Inject        IApple apple;        // -> Apple1
    @Inject @Black IApple blackApple;   // -> Apple2
    @Inject @Red   IApple redApple;     // -> Error: not defined
}

我想要的是,如果没有定义具有特定限定符的组件,我想给出一个默认值,因此上面示例中的redApple将注入一个{{1}的实例}。

有可能吗?或者我可以为Spring DI实现特定的限定符匹配策略吗?

**编辑**

我知道子类可以工作,但这是一个描述问题的例子,所以子类在这里不适用。

1 个答案:

答案 0 :(得分:4)

如果你尝试注入一些没有bean存在的资格:喜欢 @Inject @Red IApple redApple;然后你会得到:NoSuchBeanDefinitionException

无论您使用以下内容,都会发生此异常:

  • @注入
  • @Resource
  • @Autowire

原因很简单:Spring DI首次搜索确定所有候选人。

  • 如果只有一个,则使用此候选人
  • 如果没有候选者,则会引发NoSuchBeanDefinitionException
  • 如果有多于一个,它会尝试从候选人中确定候选人。
  

@see   org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency

     

第785..809行(3.0.4.RELEASE)

所以你需要做的是将退回(Apple)放在一组候选人中,但要确保只在没有其他候选人的情况下使用它。因为没有办法将bean标记为后退或更少的importend,所以需要将普通bean标记为更重要:@primary

所以(经证实的)解决方案将是注释

  • 黑人和红苹果与@Black和@Red以及@Primary。
  • 使用@Red和@Black的默认后备Apple(Apple1),但没有@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 Reference Documentation: 3.9.4 CustomAutowireConfigurer