Как я могу использовать @ConditionalOnBean
с квалификаторами в Spring?
В следующем автономном примере: у меня
- интерфейс службы
SomeService
- интерфейс адаптера
SomeAdapter
- a
GreenService
реализация SomeService
с квалификатором @Green
, в зависимости от SomeAdapter
с квалификатором @Green
BlueService
реализация SomeService
с квалификатором @Blue
, в зависимости от SomeAdapter
с квалификатором @Blue
- необязательная
GreenAdapter
реализация SomeAdapter
с квалификатором @Green
- необязательная
BlueAdapter
реализация SomeAdapter
с квалификатором @Blue
@ Зеленый квалификатор:
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Green { }
@ Синий квалификатор:
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Blue { }
GreenService:
@Green
@Service
@ConditionalOnBean(value = SomeAdapter.class, annotation = Green.class)
public class GreenService implements SomeService {
@Autowired
@Green
private SomeAdapter adapter;
}
BlueService:
@Blue
@Service
@ConditionalOnBean(value = SomeAdapter.class, annotation = Blue.class)
public class BlueService implements SomeService {
@Autowired
@Blue
private SomeAdapter adapter;
}
GreenAdapter:
@Green
@Component
public class GreenAdapter implements SomeAdapter {}
BlueAdapter:
@Blue
@Component
public class BlueAdapter implements SomeAdapter {}
Тест чтобы проверить активацию бина (не содержит BlueAdapter
, поэтому BlueService
не будет активен):
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {GreenService.class, BlueService.class, GreenAdapter.class})
public class GreenBlueServiceTest {
@Autowired
@Green
private Optional<SomeService> greenService;
@Autowired
@Blue
private Optional<SomeService> blueService;
@Test
public void testGreen() {
assertTrue(greenService.isPresent());
}
@Test
public void testBlue() {
assertFalse(blueService.isPresent());
}
}
Проблема : тест выигран ' бегать, сообщая отсутствует зависимость (SomeAdapter
с квалификатором @Blue
для BlueService
). @ConditionalOnBean
должен отключить bean-компонент, поскольку SomeAdapter
с квалификатором @Blue
отсутствует, но это не сработало.
Я обнаружил, что при добавлении аннотации @TrueBlue
(аналогично * 1078) *, но не помечен как @Annotation
) для BlueAdapter
, и используйте эту аннотацию для активации bean-компонента на BlueService
, он работает так, как должен (тестируйте все зеленым).
В заключение:
- условная активация bean с необходимыми аннотациями работает (в принципе)
- она не работает, однако, когда требуется аннотация
@Qualifier
Is это ошибка, или по дизайну, и как мне добиться такой условной активации, которая зависит от квалифицированного бина в Spring ?
РЕДАКТИРОВАТЬ: ответ @ bruno-leite объясняет, почему он не работает (аннотация и тип бина могут совпадать на разных бинах), но остается вопрос:
Как вы можете условно активировать бин, если другой бин данного типа И данная аннотация (или спецификатор c) ESENT