Это не цель аннотации @Qualifier
, чтобы использовать ее при получении bean-компонентов через ApplicationContext. Но так как вам нужны такие или подобные функции по некоторым причинам, я предлагаю обходной путь.
Создать @Wanted
и @NotWanted
аннотация:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD,
ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Wanted {
}
и
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD,
ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface NotWanted {
}
аннотирования классы боба с этими новыми аннотациями:
@Component
@NotWanted
public class NotWantedService implements Service {}
и
@Component
@Wanted
public class WantedService implements Service {}
Затем вы должны добавить 2 метода где-то, где у вас есть доступ к ApplicationContext
:
ApplicationContext applicationContext;
private <T> Collection<T> getBeansByTypeAndAnnotation(Class<T> clazz, Class<? extends Annotation> annotationType){
Map<String, T> typedBeans = applicationContext.getBeansOfType(clazz);
Map<String, Object> annotatedBeans = applicationContext.getBeansWithAnnotation(annotationType);
typedBeans.keySet().retainAll(annotatedBeans.keySet());
return typedBeans.values();
}
private <T> Optional<T> getBeanByTypeAndAnnotation(Class<T> clazz, Class<? extends Annotation> annotationType) {
Collection<T> beans = getBeansByTypeAndAnnotation(clazz, annotationType);
return beans.stream().findFirst();
}
И теперь вы можете использовать их, чтобы получить бобы или один боб с помощью аннотаций и типа, как это:
Collection<Service> services = getBeansByTypeAndAnnotation(Service.class, Wanted.class);
или
Service service = getBeanByTypeAndAnnotation(Service.class, Wanted.class);
Возможно, это не самый лучший способ DEA с этой проблемой. Но так как мы не можем получить beans из ApplicationContext
с помощью квалификатора и введите «из коробки», это один из способов сделать это.
Почему бы не получить bean по имени, так как вы используете постоянное имя, то есть 'ctx.getBean (« Wanted »)'? – aux
@aux У вас есть 50 мест, где вы делаете 'ctx.getBean (" service1 ")', и теперь вы хотите изменить его на 'ctx.getBean (" service2 ")'. Это 50 изменений. Изменение классификатора - это изменение только на 2 определения bean ('service1' и' service2'). Есть и другие случаи - скажем, я хочу получить несколько экземпляров 'Service', которые' Wanted'. Они не могут иметь одинаковое имя. –
ОК, я вижу. Тогда как насчет введения собственного «реестра», который содержит ссылки на ваши бобы и используется для поиска по различным параметрам, например «Репозитории» в режиме «весенние данные»? Или фасоль-обертка? – aux