Spring框架-注入bean的子集
我试图在spring中控制依赖项注入,以便通过Spring框架-注入bean的子集,spring,dependency-injection,autowired,tagging,Spring,Dependency Injection,Autowired,Tagging,我试图在spring中控制依赖项注入,以便通过@Autowired注释只注入bean的一个子集,但我还没有找到一个提供这种行为的解决方案 假设有一个场景,其中有许多特定类型的bean,但您只希望在各种上下文中使用特定bean。@Autowired注释支持bean集合,但它似乎不支持对可以注入的各种bean应用限制(AFAIK) @配置 公共类Impl{ @自动连线(标记={“A”}) 设置beansForContextA; @自动连线(标签={“B”}) 设置beansForContextB;
@Autowired
注释只注入bean的一个子集,但我还没有找到一个提供这种行为的解决方案
假设有一个场景,其中有许多特定类型的bean,但您只希望在各种上下文中使用特定bean。@Autowired
注释支持bean集合,但它似乎不支持对可以注入的各种bean应用限制(AFAIK)
@配置
公共类Impl{
@自动连线(标记={“A”})
设置beansForContextA;
@自动连线(标签={“B”})
设置beansForContextB;
public void execute(){
for(Foo-Foo:someCondition?beansForContextA:beansForContextB){
...
}
}
}
这里我希望beansForContextA
有bean1
和bean3
和beansForContextB
有bean2
和bean3
。这可能是通过扩展@Autowired
和@Bean
注释来支持“标记”来实现的,但我很好奇是否有现成的解决方案,或者我必须发明自己的解决方案
或者,这是一个好主意吗?也许还有另一种方法我还没有遇到。另一个简单的解决方案是使用新注释。通过spring收集bean,并通过新注释删除不需要的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
}
@Bean
Foo bean1TypeA(){
Foo-Foo=新的Foo();
foo.setType(“typeA”);
返回新的Foo();
}
@豆子
Foo bean2TypeA(){
Foo-Foo=新的Foo();
foo.setType(“typeA”);
返回新的Foo();
}
@豆子
Foo bean1TypeB(){
Foo-Foo=新的Foo();
foo.setType(“typeB”);
返回新的Foo();
}
@豆子
Foo bean2TypeB(){
Foo-Foo=新的Foo();
foo.setType(“typeB”);
返回新的Foo();
}
@自动连线
@BeanTag(“A型”)
私人收藏类型A;
@自动连线
@BeanTag(“B型”)
私人收藏类型B;
@施工后
public void removeNotNeedType(){
//使用@BeanTag remove not need bean查找所有字段
}
注释可以实现这一点。开箱即用,您可以使用字符串来限定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() {
...
}
}
有了这些自定义注释,您将得到类似这样的结果
@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) {
...
}
}
}
@配置
公共类Impl{
@自动连线
@阿斯科普
设置beansForContextA;
@自动连线
@BScope
设置beansForContextB;
public void execute(){
for(Foo-Foo:someCondition?beansForContextA:beansForContextB){
...
}
}
}
我喜欢这个解决方案,它非常简单。我个人希望看到一个只有注释的解决方案,这样注释就不会以任何方式与类型耦合,我不需要有@PostConstruct
实现,但我还是投了赞成票。这正是我需要的。关于@Qualifier
的信息对于简化用例也很有用,谢谢分享!
@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() {
...
}
}
@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) {
...
}
}
}