我想要基于从客户端传递的字符串参数注入bean。
public interface Report {
generateFile();
}
public class ExcelReport extends Report {
//implementation for generateFile
}
public class CSVReport extends Report {
//implementation for generateFile
}
class MyController{
Report report;
public HttpResponse getReport() {
}
}
我希望根据传递的参数注入报告实例。任何帮助都将非常感激。提前感谢
使用工厂方法模式
public enum ReportType {EXCEL, CSV};
@Service
public class ReportFactory {
@Resource
private ExcelReport excelReport;
@Resource
private CSVReport csvReport
public Report forType(ReportType type) {
switch(type) {
case EXCEL: return excelReport;
case CSV: return csvReport;
default:
throw new IllegalArgumentException(type);
}
}
}
报表类型enum
可以由Spring在使用?type=CSV
调用控制器时创建:
class MyController{
@Resource
private ReportFactory reportFactory;
public HttpResponse getReport(@RequestParam("type") ReportType type){
reportFactory.forType(type);
}
}
然而,ReportFactory
是相当笨拙的,需要修改每次添加新的报告类型。如果报告类型列表已修复,则没问题。但是,如果您计划添加越来越多的类型,这是一个更健壮的实现:
public interface Report {
void generateFile();
boolean supports(ReportType type);
}
public class ExcelReport extends Report {
publiv boolean support(ReportType type) {
return type == ReportType.EXCEL;
}
//...
}
@Service
public class ReportFactory {
@Resource
private List<Report> reports;
public Report forType(ReportType type) {
for(Report report: reports) {
if(report.supports(type)) {
return report;
}
}
throw new IllegalArgumentException("Unsupported type: " + type);
}
}
在这个实现中,添加新的报告类型就像添加新的bean实现Report
和一个新的ReportType
enum值一样简单。您可以不使用enum
而使用字符串(甚至可能是bean名称),但是我发现强类型是有益的。
最后的想法:Report
的名字有点不幸。Report
类表示对某些逻辑(策略模式)的(无状态?)封装,而其名称表明它封装了值(数据)。我建议ReportGenerator
之类的