java – 关于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实现特定的限定符匹配策略吗?
**编辑**
我知道子类可以工作,但这是一个描述问题的例子,所以子类在这里不适用.
解决方法:
如果你试图注入一些没有bean的限定条件:比如
@Inject @Red IApple redApple;然后你会得到一个:NoSuchBeanDefinitionException.
如果您使用以下情况,则会发生此异常:
> @Inject
> @Resource
> @Autowire
原因很简单:Spring DI首次搜索确定所有autowire候选者.
>如果只有一个,它就会使用这个候选者
>如果没有候选者,则会引发NoSuchBeanDefinitionException
>如果有多于一个,它试图确定候选人中的候选人.
@See
org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependencyline 785..809 (3.0.4.RELEASE)
所以你需要做的是将退回(苹果)放在一组候选人中,但要确保只有在没有其他候选人时才使用它.因为没有办法将bean标记为后退或更少的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 Reference Documentation: 3.9.4 CustomAutowireConfigurer
标签:java,dependency-injection,spring,jsr330 来源: https://codeday.me/bug/20190626/1296832.html