Reputation: 6543
I have a problem to select the correct spring bean that should get injected. I need a way to tell the spring container what bean to inject depeding on the call to a previous class. I do all the spring bean wiring in xml.
My question: is this possible and if it is any reference on an implementation?
I have created some sample code to illustrate what i´m trying to accomplish. Feel free to change it so that it will work to get the correct ReportHeader bean injected depending on the selected reportType during runtime.
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();
}
}
Upvotes: 0
Views: 318
Reputation: 10632
You can define a ReportHeaderFactory
to get the ReportHeader
according to ReportType
:
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");
}
}
}
Re-define the ReportHeaderService
with an instance of ReportHeaderFactory
:
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);
}
}
As you are doing all the spring bean wiring in xml, you just need to make below entries in the config file:
<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" />
Upvotes: 1
Reputation: 40036
Consider injecting a Map<ReportType, ReportHeader>
to ReportHeaderService, so that generateHeader works as:
public class ReportHeaderService {
private Map<ReportType, ReportHeader> reportHeaderMap;
public void generateHeader(ReportType type){
ReportHeader reportHeader = reportHeaderMap.get(type);
if (reportHeader != null) {
reportHeader.createHeader();
}
}
}
Upvotes: 3