Java 在运行时选择Springbean

Java 在运行时选择Springbean,java,spring,dependency-injection,Java,Spring,Dependency Injection,我在选择正确的springbean时遇到了一个问题。 我需要一种方法,根据对前一个类的调用来告诉spring容器注入什么bean。我用xml进行所有Springbean连接 我的问题:这可能吗?它是否是实现的参考 我已经创建了一些示例代码来说明我试图实现的目标。您可以随意更改它,以便在运行时根据所选的reportType注入正确的ReportHeader bean public enum ReportType{ Credit, Annul } public class R

我在选择正确的springbean时遇到了一个问题。 我需要一种方法,根据对前一个类的调用来告诉spring容器注入什么bean。我用xml进行所有Springbean连接

我的问题:这可能吗?它是否是实现的参考

我已经创建了一些示例代码来说明我试图实现的目标。您可以随意更改它,以便在运行时根据所选的reportType注入正确的ReportHeader bean

public enum ReportType{
    Credit,
    Annul   
}

public class ReportService {

    private ReportHeaderService reportHeaderService;
    private ReportType reportType;

    public ReportService (){}

    public setReportType(ReportType reportType){
        this.reportType = reportType;
    }

    public void setReportHeaderService(ReportHeaderService reportHeaderService){
        this.reportHeaderService = reportHeaderService;
    }

    private void generateHeader(){
        //i would like to call my service like this and have the correct bean injected to ReportHeader.
        reportHeaderService.generateHeader(reportType)
    }
}

public class ReportHeaderService {

    private ReportHeader reportHeader;

    //this will call the injected bean that needs to be selected accoring to the ReportType
    public void generateHeader(ReportType type){
        reportHeader.createHeader();
    }
}

public interface ReportHeader{
    public void createHeader();
}

public class CreditReportHeader implements ReportHeader{
    public void createHeader(){
        ..dostuff();
    }
}

public class AnnulReportHeader implements ReportHeader{
    public void createHeader(){
        ..dostuff();
    }
}

考虑将
Map
注入ReportHeaderService,以便generateHeader的工作方式如下:

public class ReportHeaderService {

    private Map<ReportType, ReportHeader> reportHeaderMap;

    public void generateHeader(ReportType type){
        ReportHeader reportHeader = reportHeaderMap.get(type);
        if (reportHeader != null) {
            reportHeader.createHeader();
        }
    }
}
公共类ReportHeaderService{
私有地图报表头映射;
公共无效生成器标头(报表类型){
ReportHeader ReportHeader=reportHeaderMap.get(类型);
if(reportHeader!=null){
reportHeader.createHeader();
}
}
}

考虑向ReportHeaderService注入一个
映射,这样generateHeader就可以:

public class ReportHeaderService {

    private Map<ReportType, ReportHeader> reportHeaderMap;

    public void generateHeader(ReportType type){
        ReportHeader reportHeader = reportHeaderMap.get(type);
        if (reportHeader != null) {
            reportHeader.createHeader();
        }
    }
}
公共类ReportHeaderService{
私有地图报表头映射;
公共无效生成器标头(报表类型){
ReportHeader ReportHeader=reportHeaderMap.get(类型);
if(reportHeader!=null){
reportHeader.createHeader();
}
}
}

您可以根据
ReportType
定义一个
ReportHeaderFactory
来获取
ReportHeader

public class ReportHeaderFactory {
    private CreditReportHeader creditReportHeader;
    private AnnulReportHeader annulReportHeader;

    public ReportHeader getReportHeader(ReportType reportType) {
        switch (reportType) {
        case Credit:
            return creditReportHeader;
        case Annul:
            return annulReportHeader;
        default:
            throw new IllegalArgumentException("No Such Header");
        }
    }
}
使用
ReportHeaderFactory
的实例重新定义
ReportHeaderService

public class ReportHeaderService {

    //private ReportHeader reportHeader;
    private ReportHeaderFactory headerFactory;

    //this will call the injected bean that needs to be selected accoring to the ReportType
    public void generateHeader(ReportType type){
        //reportHeader.createHeader();
        headerFactory.getReportHeader(type);
    }
}
在xml中执行所有SpringBean连接时,只需在配置文件中创建以下条目:

    <bean id="ReportHeaderService" class="x.y.ReportHeaderService">
        <property name="headerFactory" ref="headerFactory" />
    </bean>

    <bean id="headerFactory" class="x.y.ReportHeaderFactory">
        <property name="creditReportHeader" ref="creditReportHeader" />
        <property name="annulReportHeader" ref="annulReportHeader" />
    </bean>

    <bean id="creditReportHeader" class="x.y.CreditReportHeaderImpl" />
    <bean id="annulReportHeader" class="x.y.AnnulReportHeaderImpl" />

您可以根据
ReportType
定义一个
ReportHeaderFactory
来获取
ReportHeader

public class ReportHeaderFactory {
    private CreditReportHeader creditReportHeader;
    private AnnulReportHeader annulReportHeader;

    public ReportHeader getReportHeader(ReportType reportType) {
        switch (reportType) {
        case Credit:
            return creditReportHeader;
        case Annul:
            return annulReportHeader;
        default:
            throw new IllegalArgumentException("No Such Header");
        }
    }
}
使用
ReportHeaderFactory
的实例重新定义
ReportHeaderService

public class ReportHeaderService {

    //private ReportHeader reportHeader;
    private ReportHeaderFactory headerFactory;

    //this will call the injected bean that needs to be selected accoring to the ReportType
    public void generateHeader(ReportType type){
        //reportHeader.createHeader();
        headerFactory.getReportHeader(type);
    }
}
在xml中执行所有SpringBean连接时,只需在配置文件中创建以下条目:

    <bean id="ReportHeaderService" class="x.y.ReportHeaderService">
        <property name="headerFactory" ref="headerFactory" />
    </bean>

    <bean id="headerFactory" class="x.y.ReportHeaderFactory">
        <property name="creditReportHeader" ref="creditReportHeader" />
        <property name="annulReportHeader" ref="annulReportHeader" />
    </bean>

    <bean id="creditReportHeader" class="x.y.CreditReportHeaderImpl" />
    <bean id="annulReportHeader" class="x.y.AnnulReportHeaderImpl" />


这当然是一个可行的解决方案,但我希望避免注入多个bean。这当然是一个可行的解决方案,但我希望避免注入多个bean。这当然是一个可行的解决方案,但我希望避免注入多个bean,因为我想所有的bean都将注入映射,而不仅仅是在映射上调用get后加载?如果您希望它是延迟加载的,那么应该允许您向映射注入延迟加载代理,而不是实际的bean。您可能需要研究的另一件事是decorator模式:您可以创建一个ReportHeader impl,它负责委托createHeader()的工作打电话给正确的人。当然,ReportType需要是createHeader()的一个输入参数这当然是一个可行的解决方案,但我希望避免注入多个bean,因为我猜所有bean都将注入到映射中,而不仅仅是在映射上调用get后才加载?如果希望延迟加载,应该允许您向映射注入延迟加载代理,而不是实际的bean。您可能需要研究的另一件事是decorator模式:您可以创建一个ReportHeader impl,它将createHeader()调用委托给正确的调用。当然,ReportType需要是createHeader()的输入参数