我试图控制 spring 中的依赖注入(inject),以便仅通过 @Autowired 注释注入(inject)一部分 bean,但我还没有遇到提供此行为的解决方案。
想象一个场景,有许多某种类型的 bean,但您只想在不同的上下文中使用某些 bean。 @Autowired
注释支持 bean 集合,但它似乎不支持对可注入(inject)的各种 bean 施加限制(AFAIK)。
@Autowired
Set<Foo> beansForContextA;
@Autowired
Set<Foo> beansForContextB;
上面的代码将把相同的一组bean注入(inject)到beansForContextA
和beansForContextB
中。我想要一种方法来区分哪些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) {
...
}
}
}
在这里,我希望 beansForContextA
有 bean1
和 bean3
和 beansForContextB
有 bean2
和 bean3
。这可能可以通过扩展 @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/