Java – conditionally inject beans

I want to inject a bean based on the string parameter passed from the client

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() {
    }
}

I want to inject report instances based on the parameters passed Any help would be very useful Thank you in advance

Solution

Use factory method mode:

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);
        }
    }
}

When you use? Type = when CSV calls the controller, spring can create an enumeration of report types:

class MyController{

    @Resource
    private ReportFactory reportFactory;

    public HttpResponse getReport(@RequestParam("type") ReportType type){
        reportFactory.forType(type);
    }

}

However, reportfactory is very clumsy and needs to be modified every time a new report type is added If the list of report types is fixed, there is no problem But if you plan to add more and more types, this is a more powerful implementation:

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);
    }
}

With this implementation, adding a new report type is as simple as adding a new bean to implement report and a new reporttype enumeration value You can leave without enumerating and using strings (maybe even bean names), but I find strong typing useful

Finally, I thought: the name of the report is a little unfortunate Report class representation (stateless?) The encapsulation of some logic (strategy pattern), and the name indicates that it encapsulates values (data) I'll suggest report generator and so on

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>