在Spring中注入不同bean的多个实例

Fyn*_*ynn 5 java spring dependency-injection

我试图解决Spring DI的问题.我有两个bean(MyFirstBean&MySecondBean)都实现了给定的接口(MyBean).然后我有多个其他bean(例如OtherBean),我想与两个bean中的任何一个使用.自动装配显然失败,OtherBean因为有多个实例MyBean可供选择.是否有可能通常MyBean使用限定符创建自动装配并引用它们的每个bean的两个实例?我知道这可以通过编写配置类来实现,但由于所有这些都是API的一部分,我希望尽可能降低开销.

现在的情况:

public interface MyBean {
}

@Component
public class MyFirstBean implements MyBean {
}

@Component
public class MySecondBean implements MyBean {
}

@Component
public class OtherBean {

    final MyBean myBean; // error due to multiple beans

    public OtherBean(MyBean myBean) {
        this.myBean = myBean;
    }
}
Run Code Online (Sandbox Code Playgroud)

期望情况:

@Component
public class SomeBean {

    final OtherBean myBeanUsingFirstBean; // internally autowires MyFirstBean

    final OtherBean myBeanUsingSecondBean; // internally autowires MySecondBean

    public SomeBean(
        @FirstBeanQualifier OtherBean myBeanUsingFirstBean,
        @SecondBeanQualifier OtherBean myBeanUsingSecondBean) {
        this.myBeanUsingFirstBean = myBeanUsingFirstBean;
        this.myBeanUsingSecondBean = myBeanUsingSecondBean;
    }
}
Run Code Online (Sandbox Code Playgroud)

Sea*_*uit 6

解决方案1:

春天自动装豆的方法之一就是名字.如果没有指定,spring将使用类名创建bean(带小的首字母),因此对于MyFirstBean,bean名称将是myFirstBean.知道您可以通过将属性的名称更改为最终的MyBean myFirstBean来自动装配所需的bean

public interface MyBean {
}

@Component
public class MyFirstBean implements MyBean {
}

@Component
public class MySecondBean implements MyBean {
}

@Component
public class OtherBean {

    // this way spring will inject instance of MyFirstBean
    @Autowired
    final MyBean myFirstBean ; 

}
Run Code Online (Sandbox Code Playgroud)

解决方案2:

有时我喜欢手动分配bean.所以我将所有可用的bean自动装入列表中,然后在@PostConstruct中你做逻辑:

@Autowired
private List<MyBean> myBeans;
Run Code Online (Sandbox Code Playgroud)

解决方案3:

使用@Qualifier注释

public interface MyBean {
}

@Component("fooBean")
public class MyFirstBean implements MyBean {
}

@Component
public class MySecondBean implements MyBean {
}

@Component
public class OtherBean {

    @Autowired
    @Qualifier("fooBean")
    final MyBean myFirstBean ; 

}
Run Code Online (Sandbox Code Playgroud)

解决方案4:

自定义注释

@Qualifier
@Target({
ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, 
ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyBeanType {
   String value();
}


public interface MyBean {
}

@MyBeanType("fooBean")
@Component()
public class MyFirstBean implements MyBean {
}

@MyBeanType("barBean")
@Component
public class MySecondBean implements MyBean {
}

@Component
public class OtherBean {

    @Autowired
    @MyBeanType("Foo")
    final MyBean myBean ; 

}
Run Code Online (Sandbox Code Playgroud)


Dar*_*ice 1

您可以将 @Qualifier 添加到您的 bean 中以区分不同的 bean。注入 Bean 时,您可以使用指定的限定符来注入正确的 Bean。