Java 如何实现spring限定符的OR逻辑?

Java 如何实现spring限定符的OR逻辑?,java,spring,spring-boot,autowired,Java,Spring,Spring Boot,Autowired,我有以下配置: @Qualifier1 @Qualifier2 @Bean public MyBean bean1(){...} @Qualifier2 @Qualifier3 @Bean public MyBean bean2(){...} @Qualifier1 @Qualifier2 @Qualifier3 @Bean public MyBean bean3(){...} @Qualifier3 @Bean public MyBean bean4(){...} @Qualifier

我有以下配置:

@Qualifier1
@Qualifier2
@Bean
public MyBean bean1(){...}

@Qualifier2
@Qualifier3
@Bean
public MyBean bean2(){...}

@Qualifier1
@Qualifier2
@Qualifier3
@Bean
public MyBean bean3(){...}

@Qualifier3
@Bean
public MyBean bean4(){...}

@Qualifier1
@Bean
public MyBean bean5(){...}
这是注射的地方:

@Qualifier2
@Qualifier3
@Autowired:
private List<MyBean> beans;

如果使用标记接口而不是限定符会怎么样?例如:

公共类MyBean1扩展MyBean实现Marker1{}
公共类MyBean2扩展MyBean实现Marker2{}
公共类MyBean12扩展MyBean实现Marker1、Marker2{}
然后使用这个:

@Bean
公共MyBean1 MyBean1(){
//...
}
@豆子
公共MyBean2 MyBean2(){
//...
}
@豆子
公共MyBean12 MyBean12(){
//...
}
这是:

@Autowired private List myBeans;
您将获得
myBean1
myBean12
bean的列表

为此:

@Autowired private List myBeans;
您将获得
myBean2
myBean12
bean的列表

这样行吗

更新I

定制FactoryBean

我实现了类和注释,您可以使用它们来解决您的任务(我希望:)

首先,用
@Tags
注释标记bean:

@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Qualifier1 {
}
@标记({“问候语”、“两个字母”})
@豆子
公共供应商hi(){
返回()->“hi”;
}
@标签({“分开”,“两个字母”})
@豆子
公共供应商{
return()->“by”;
}
@标签(“问候语”)
@豆子
公共供应商hello(){
return()->“你好”;
}
@标签(“分开”)
@豆子
公共服务供应商(){
return()->“再见”;
}
@标签(“其他”)
@豆子
公共供应商其他(){
返回()->“其他”;
}
然后准备
标记FactoryBean

@Bean
公共标记FactoryBean单词(){
返回标记FactoryBean.builder()
.标签(“问候语”、“其他”)
.类型(供应商.类别)
.generics(String.class)
.build();
}
这里,
tags
是所需标记的数组,应选择其bean,
type
是所选bean类型,
generics
是bean的泛型类型数组。最后一个参数是可选的,仅当您的bean是泛型的时才应使用

然后您可以将其与
@限定符
注释一起使用(否则Spring将注入
供应商
类型的所有bean):

@Autowired
@限定词(“词”)
私有地图豆;
映射
bean
将包含三个bean:
hi
hello
other
(它们的名称是映射的键,它们的实例是映射的值)

您可以在中找到更多使用示例

更新II

自定义自动线解算器

多亏了@bhosleviraj,我实现了简化自动连接所需bean的过程。只需使用相同的标记标记您的bean和autowired集合,您就可以将它们注入到集合中:

@Autowired
@标签({“问候语”、“其他”})
私人地图接机或其他;
@配置
静态类bean{
@标记({“问候语”、“2符号”、“偶数”})
@豆子
公共供应商hi(){
返回()->“hi”;
}
@标记({“分开”、“2符号”、“偶数”})
@豆子
公共供应商{
return()->“by”;
}
@标签({“问候语”、“5符号”、“奇数”})
@豆子
公共供应商hello(){
return()->“你好”;
}
@标记({“分离”、“7符号”、“奇数”})
@豆子
公共服务供应商(){
return()->“再见”;
}
@标记({“其他”、“5符号”、“奇数”})
@豆子
公共供应商其他(){
返回()->“其他”;
}
}
您不仅可以使用映射来注入bean,还可以使用其他集合

要使其正常工作,您必须在应用程序中注册一个
CustomAutowireConfigurer
bean,并为其提供
标记DautoWireCandidateResolver

@配置
公共类自动配置{
@豆子
公共CustomAutowireConfigurer autowireConfigurer(DefaultListableBeanFactory beanFactory){
CustomAutowireConfigurer configurer=新CustomAutowireConfigurer();
setAutowireCandidateResolver(新标记DautoWireCandidateResolver());
配置器。后处理beanFactory(beanFactory);
返回配置器;
}
}

更多使用示例见此。

我想您不能使用注释

我使用的是
org.springframework.context.ApplicationContextAware
也许您需要编写一些额外的代码,但通过这种方式您可以解决您的问题

我将实现这样一个类:

@Component
public class SpringContextAware implements ApplicationContextAware {
    public static ApplicationContext ctx;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }
    public static synchronized ApplicationContext getCtx() {
        return ctx;
    }
}
@Autowired
private SpringContextAware ctxAware;
@PostConstruct
public void init() {
    //Here you can do your OR logic
    ctxAware.getCtx().getBean("qualifier1") or ctxAware.getCtx().getBean("qualifier2") 
}
然后,在所有需要或逻辑的bean中,您可以执行以下操作:

@Component
public class SpringContextAware implements ApplicationContextAware {
    public static ApplicationContext ctx;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ctx = applicationContext;
    }
    public static synchronized ApplicationContext getCtx() {
        return ctx;
    }
}
@Autowired
private SpringContextAware ctxAware;
@PostConstruct
public void init() {
    //Here you can do your OR logic
    ctxAware.getCtx().getBean("qualifier1") or ctxAware.getCtx().getBean("qualifier2") 
}
这能解决你的问题吗


Angelo

答案需要深入了解自动布线解决方案在Spring中是如何实现的,因此我们可以扩展它。 我还不能想出任何解决办法,但我可以给你一些建议。 可能要扩展的候选对象是限定符AnnotationAutowireCandidateResolver,重写解析为限定bean的方法。并将自定义autowire解析器传递给bean工厂。 您可以从此处克隆源代码并更正版本分支:


SpringBeans模块中有一个CustomAutowireConfigurerTests,可以帮助您了解一些事情。

您确定描述正确吗
所以bean2和bean3将被注入
vs
所以我希望bean1、bean2、bean3和bean4被注入
@Eugene你能详细说明一下吗?AR是如此之多,bean2和bean3将被注射,但我想要另一个behaviour@Eugene我想注入bean,如果它至少有一个匹配的限定符,你是说如果某个基于
限定符x
的限定符已经加载到上下文中,你不想将另一个具有相同限定符x的bean加载到上下文中吗?@Eugene我想要所有bean我想通过几个标记自动连接。在您的情况下,我希望自动连接所有实现接口Marker1、Marker2的bean。看起来像你的方法