我想根据从客户端传递的String参数注入一个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() {
- }
- }
我希望根据传递的参数注入报表实例.任何帮助都会非常有用.提前致谢
解决方法
使用
Factory method模式:
- 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);
- }
- }
- }
当您使用?type = CSV调用控制器时,Spring可以创建报告类型枚举:
- 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枚举值一样简单.你可以在没有枚举和使用字符串(甚至可能是bean名称)的情况下离开,但是我发现强类型很有用.
最后想到:报告名称有点不幸.报告类表示(无状态?)某些逻辑(Strategy模式)的封装,而名称表明它封装了值(数据).我会建议ReportGenerator等.