Spring 框架 - 注入(inject) bean 子集

标签 spring dependency-injection autowired tagging

我试图控制 spring 中的依赖注入(inject),以便仅通过 @Autowired 注释注入(inject)一部分 bean,但我还没有遇到提供此行为的解决方案。

想象一个场景,有许多某种类型的 bean,但您只想在不同的上下文中使用某些 bean。 @Autowired 注释支持 bean 集合,但它似乎不支持对可注入(inject)的各种 bean 施加限制(AFAIK)。

@Autowired
Set<Foo> beansForContextA;

@Autowired
Set<Foo> beansForContextB;

上面的代码将把相同的一组bean注入(inject)到beansForContextAbeansForContextB中。我想要一种方法来区分哪些bean被注入(inject)到它各自的属性中。 spring 中是否有内置的东西支持这个用例?

考虑以下伪代码来更清楚地说明期望:

@Configuration
public class Config {
    @Bean(tags = {"A"})
    Foo bean1() {
        ...
    }

    @Bean(tags = {"B"})
    Foo bean2() {
        ...
    }

    @Bean(tags = {"A", "B"})
    Foo bean3() {
        ...
    }
}

@Configuration
public class Impl {
    @Autowired(tags = {"A"})
    Set<Foo> beansForContextA;

    @Autowired(tags = {"B"})
    Set<Foo> beansForContextB;

    public void execute() {
        for (Foo foo : someCondition ? beansForContextA : beansForContextB) {
            ...
        }
    }
}

在这里,我希望 beansForContextAbean1bean3beansForContextBbean2bean3。这可能可以通过扩展 @Autowired 和 @Bean 注释来支持“标签”来实现,但我很好奇是否有一个已经解决的解决方案或将我必须发明自己的吗?

或者,这是一个好主意吗?也许还有另一种我还没有遇到过的方法。

最佳答案

@Qualifier注释可以实现这一点。开箱即用,您可以使用字符串来限定 bean 和注入(inject)点:

@Autowired
@Qualifier("a")
Set<Foo> beansForContextA;

@Autowired
@Qualifier("b")
Set<Foo> beansForContextB;


@Configuration
public class Config {
    @Bean
    @Qualifier("a")
    Foo bean1() {
        ...
    }

    @Bean
    @Qualifier("b")
    Foo bean2() {
        ...
    }
}

但这在您的情况下不起作用,因为 @Qualifier 的多个实例不能出现在同一位置。 You have to create custom annotations which are annotated with Qualifier and use those instead of @Qualifier and a string name.

@Target(value={FIELD,METHOD,PARAMETER,TYPE,ANNOTATION_TYPE})
 @Retention(value=RUNTIME)
 @Inherited
 @Qualifier
public interface AScope

@Target(value={FIELD,METHOD,PARAMETER,TYPE,ANNOTATION_TYPE})
 @Retention(value=RUNTIME)
 @Inherited
 @Qualifier
public interface BScope

使用这些自定义注释,您最终会得到类似这样的结果。

@Configuration
public class Config {
    @Bean
    @AScope
    Foo bean1() {
        ...
    }

    @Bean
    @BScope
    Foo bean2() {
        ...
    }

    @Bean
    @AScope
    @BScope
    Foo bean3() {
        ...
    }
}

在注入(inject)点:

@Configuration
public class Impl {
    @Autowired
    @AScope
    Set<Foo> beansForContextA;

    @Autowired
    @BScope
    Set<Foo> beansForContextB;

    public void execute() {
        for (Foo foo : someCondition ? beansForContextA : beansForContextB) {
            ...
        }
    }
}

关于Spring 框架 - 注入(inject) bean 子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57173262/

相关文章:

java - Spring Boot - JNDI 值查找

asp.net-mvc - Fluent 验证和 IoC(独特字段)

java - Spring:如何通过 Autowiring 设置多个属性?

java - Freemarker 配置的 Autowiring 失败

Spring Autowire 失败,找不到类型的合格 bean 依赖错误

java - Apache Tiles 和 Spring MVC 中的全局异常页面

java - Servlet 内的 @Autowire null

java - 在 Spring MVC 应用程序中查找内存泄漏

c# - 依赖注入(inject)如何应用于这种情况?

scala - Play Scala 依赖注入(inject) : How to use it