当前位置: 首页 > 面试题库 >

有条件地注入豆

笪智志
2023-03-14
问题内容

我想基于从客户端传递的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() {
    }
}

我希望基于传递的参数注入报表实例。任何帮助将不胜感激。提前致谢


问题答案:

使用工厂方法模式:

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和使用字符串(甚至可能是bean名称)而无所事事,但是我发现强烈键入很有用。

最后的想法:Report名字有点不幸。Report类表示(无状态?)某种逻辑的封装(策略模式),而名称则表示它封装了
(数据)。我会建议ReportGenerator这样的。



 类似资料:
  • Java8/Camel 2.19. x在这里。我有以下路由XML: 所以,很简单: 在愉快路径上,从AMQ上的输入队列中消费,将其反序列化(通过XStream)为Java对象,将其发送到thingProcessor,并将该处理器的结果放在输出队列中 如果发生异常,例如thingProcessor抛出RuntimeException,我们将异常堆栈跟踪记录到应用程序日志中,然后转换原始XML(我们从

  • 问题内容: 我已经定义了这样的服务: 我希望仅为新用户实例化我的服务(即当user.createdAt>今天)。 因此,如果用户是老用户,有没有办法有条件地注入我的服务或至少销毁我的服务而没有任何副作用。 问题答案: 如果需要,您可以使用该服务动态获取可注射对象: 这是完整运行的演示:http : //jsbin.com/bemakemaja/1/edit 和文档:https : //docs.a

  • 我需要做一些事情,比如: 上面的代码无法编译;它抛出 我尝试使用,如下所示,但我不知道来自哪里。这是一个最终没有被接受的ES6提案吗?该文章中指向“编程 API”的链接将我转储到一个已弃用的文档页面。

  • 我有如下代码: 在我的属性文件中,我有: 这不起作用,parseFooBar在第一秒每分钟都被执行。 但是,如果我添加字段: 所以我可以做一个日志,看看它是什么,parseFooBar不会被执行。移除注入的字符串会再次看到parseFooBar执行。我做错了什么? 编辑:这是使用Spring 4.1.5,Spring Boot 1.2.1和JDK 8 编辑2:将注释移动到类型也有效。(无需强制使用

  • 对于在其生命周期的某个点隐藏的组件,呈现它的最佳方式是什么?1)渲染组件,但不显示它(显示:无)。2)只在需要时渲染组件。什么对性能更好?如果组件的道具和状态稍后更新,是否最好让组件存在,但隐藏在虚拟DOM中? 或者这个:

  • 我有一个rxJava2可观察对象,我想有条件地订阅它。场景i将进行网络调用,并且只有当设备连接到网络时才会调用。我想做下面的事情 有什么建议吗?有没有更好的办法?