Spring 框架 - 注入 bean 的子集



我正在尝试控制 spring 中的依赖注入,以便@Autowired注释只注入一部分 bean,但我还没有遇到提供这种行为的解决方案。

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

@Autowired
Set<Foo> beansForContextA;
@Autowired
Set<Foo> beansForContextB;

上面的代码会将同一组 bean 注入beansForContextAbeansForContextB中。我想要一种方法来区分哪些豆子被注入到它各自的属性中。弹簧中内置的东西是否支持此用例?

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

@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拥有bean1bean3beansForContextB拥有bean2bean3.这可以通过扩展@Autowired@Bean注释来支持"标签"来实现,但我很好奇是否有一个已经成熟的解决方案,或者我必须发明自己的解决方案?

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

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

@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的多个实例不能存在于同一个地方。您必须创建用Qualifier注释的自定义注释,并使用这些注释而不是@Qualifier和字符串名称。

@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() {
...
}
}

在注射点:

@Configuration
public class Impl {
@Autowired
@AScope
Set<Foo> beansForContextA;
@Autowired
@BScope
Set<Foo> beansForContextB;
public void execute() {
for (Foo foo : someCondition ? beansForContextA : beansForContextB) {
...
}
}
}

另一个简单的解决方案是使用新的注释.收集 bean by spring,并通过新的注释删除不需要的 bean。

public @interface BeanTag {
String value();
}

如何使用。

@Bean
Foo bean1TypeA() {
Foo foo = new Foo();
foo.setType("typeA");
return new Foo();
}
@Bean
Foo bean2TypeA() {
Foo foo = new Foo();
foo.setType("typeA");
return new Foo();
}
@Bean
Foo bean1TypeB() {
Foo foo = new Foo();
foo.setType("typeB");
return new Foo();
}
@Bean
Foo bean2TypeB() {
Foo foo = new Foo();
foo.setType("typeB");
return new Foo();
}
@Autowired
@BeanTag("typeA")
private Set<Foo> collectionTypeA;
@Autowired
@BeanTag("typeB")
private Set<Foo> collectionTypeB;

@PostConstruct
public void removeNotNeedType(){
// find all the field with @BeanTag remove not need bean
}

相关内容

  • 没有找到相关文章

最新更新