2011-03-16 25 views
4

通常约预选赛中的一个问题,一个合格的部件将被注入到注释字段以相同的限定词:在Spring DI

@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将被注入一个Apple1的实例。

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

**编辑**

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

回答

4

如果你尝试注入一些符合条件的东西,例如 @Inject @Red IApple redApple;那么你将得到一个:NoSuchBeanDefinitionException

此异常,如果您使用occures不管:

  • @Inject
  • @Resource
  • @Autowire

原因很简单:春天DI第一搜索确定所有autowire候选人。

  • 如果恰好有一个,在它使用这个候选人
  • 如果没有候选人,它提出一个NoSuchBeanDefinitionException
  • 如果有一个以上的,它tryes确定primery人选出来的candiates。

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

线785..809(3.0.4.RELEASE)

所以你需要什么要做的就是把倒退(苹果)放在一组选举中,但要确保只在没有其他候选人的情况下使用。因为没有办法将bean标记为后退或更少imported,所以您需要将正常bean标记为更重要:@primary

所以(证明)解决方案将被标注

  • 黑和红苹果与@Black和@Red与@Primary。
  • 与@Red和@Black但缺少@Primary的默认回退Apple(Apple1)。

例子:

@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)到您的回落豆,你可以尝试implment您自己的AutowireCandiateResolver,以便它将回退豆添加到所需的所有类型的苹果列表中(Apple) @see Reference Documentation: 3.9.4 CustomAutowireConfigurer

+0

+1最佳答案! – Nilesh 2011-03-18 13:27:01