Если вы попытаетесь ввести что-то с квалификацией, для которой не существует боба, например: @Inject @Red IApple redApple;
, вы получите: NoSuchBeanDefinitionException
.
Это исключение возникает независимо от того, используете ли вы:
- @ Inject
- @ Resource
- @ Autowire
Причина проста: сначала поиск Spring DI определяет всекандидаты autowire.
- если есть ровно один, то он использует этого кандидата
- , если кандидата нет, он вызывает NoSuchBeanDefinitionException
- , если большево-первых, он пытается определить первичного кандидата из кандидатов.
@ См. org.springframework.beans.factory.support.DefaultListableBeanFactory # doResolveDependency
, строка 785..809 (3.0.4.RELEASE)
То, что вам нужно сделать, это поместить запасной (Apple) в набор конфет, но убедитесь, что он используется только при наличиидругого кандидата нет.Поскольку нет способа пометить боб как отступившего или менее важного, вам нужно пометить нормальный боб как более важный: @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) в ваш резервный компонент, выможет попытаться внедрить свой собственный AutowireCandiateResolver
, чтобы он добавил резервный компонент во все списки кандидатов необходимого типа (Apple) @, см. справочную документацию: 3.9.4 CustomAutowireConfigurer