假设我正在创建一个具有PrinterService
对象的AbstractPrinter
类。 AbstractPrinter
是由HPPrinter
,FilePrinter
等类创建的子类。
传递给我RequestParam
的{{1}}对象中提到了要使用的确切类型的打印机对象(它是一个请求属性)。
有没有什么方法可以使用Spring注入正确类型的混凝土打印机类?
使用Controller
注释注入所有其他依赖项。如何注入这个?
答案 0 :(得分:0)
您可以为每个PrinterService
具体类创建一个专用的AbstractPrinter
实例。例如,您可以使用遵循工厂模式的Spring configuration来实现此目的:
@Configuration
public class PrinterServiceConfiguration {
@Autowired
private HPPrinter hpPrinter;
@Autowired
private FilePrinter filePrinter;
@Bean
public PrinterService hpPrinterService() {
return new PrinterService(hpPrinter);
}
@Bean
public PrinterService filePrinterService() {
return new PrinterService(filePrinter);
}
public PrinterService findPrinterService(PrinterType type){
if (type == HP)
return hpPrinterService();
....
}
}
然后在您的控制器中,注入PrinterServiceConfiguration
,然后使用正确的打印机类型调用findPrinterService
。
不要忘记在您的配置PrinterServiceConfiguration
添加@Import
。
如果打印机列表是动态的,您可以切换到原型bean:
@Configuration
public class PrinterServiceConfiguration {
@Autowired
private List<AbstractPrinter> printers;
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public PrinterService createPrinterService(PrinterType type){
return new PrinterService(findPrinterByType(type));
}
private Printer findPrinterByType(PrinterType type) {
// iterate over printers then return the printer that match type
// throw exception if no printer found
}
}
答案 1 :(得分:0)
您可以在容器启动期间创建和加载AbstractPrinter
个对象的工厂,如下所示,并动态调用相应的AbstractPrinter
&#39; print()
(或您自己的方法)基于输入参数(来自控制器)到服务。
在下面的PrinterServiceImpl
类代码中,要点是所有List<AbstractPrinter>
都将由Spring容器注入(取决于您提供的实现类数,如HPPrinter等)。 。然后,您将在容器启动期间将这些bean加载到Map
,并将printerType作为键。
@Controller
public class YourController {
@Autowired
private PrinterService printerService;
public X myMethod(@RequestParam("input") String input) {
printerService.myServiceMethod(input);
//return X
}
}
PrinterServiceImpl类:
public class PrinterServiceImpl implements PrinterService {
@Autowired
private List<AbstractPrinter> abstractPrinters;
private static final Map<String,AbstractPrinter> myPrinters = new HashMap<>();
@PostConstruct
public void loadPrinters() {
for(AbstractPrinter printer : abstractPrinters) {
myPrinters.put(printer.getPrinterType(), printer);
}
}
//Add your other Autowired dependencies here
@Override
public void myServiceMethod(String input){//get input from controller
AbstractPrinter abstractPrinter= myPrinters.get(input);
abstractPrinter.print();//dynamically calls print() depending on input
}
}
HPPrinter类:
@Component
public class HPPrinter implements AbstractPrinter {
@Override
public String getPrinterType() {
return "HP";
}
@Override
public void print() {
// Your print code
}
}
FilePrinter类:
@Component
public class FilePrinter implements AbstractPrinter {
@Override
public String getPrinterType() {
return "FILE";
}
@Override
public void print() {
// Your print code
}
}