假设我创建了一个PrinterService
类,该类具有AbstractPrinter
对象。 AbstractPrinter
由类,如HPPrinter
,FilePrinter
等Spring MVC根据请求实例化对象属性
确切种类打印机对象的情况下使用在传递给我Controller
(它是一个请求属性)RequestParam
对象被提到的子类。
有什么办法可以使用Spring注入合适的具体打印机类? 所有其他依赖项均使用@Autowired
注释注入。如何注入这个?
假设我创建了一个PrinterService
类,该类具有AbstractPrinter
对象。 AbstractPrinter
由类,如HPPrinter
,FilePrinter
等Spring MVC根据请求实例化对象属性
确切种类打印机对象的情况下使用在传递给我Controller
(它是一个请求属性)RequestParam
对象被提到的子类。
有什么办法可以使用Spring注入合适的具体打印机类? 所有其他依赖项均使用@Autowired
注释注入。如何注入这个?
您可以创建和如下图所示的容器启动时加载工厂AbstractPrinter
对象和动态调用相应的AbstractPrinter
的print()
(或您自己的方法)基于输入参数(来自控制器)到服务。
在为PrinterServiceImpl
类下面的代码,主要的一点是,所有的List<AbstractPrinter>
将由Spring容器注入(取决于你有多少实现类提供像HPPrinter,等等)。然后,您将使用printerType作为密钥在容器启动期间将这些bean加载到Map
中。
@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
}
}
您可以创建一个专用的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
用正确的打印机类型。
不要忘记在您的配置@Import
上添加PrinterServiceConfiguration
。
如果打印机的列表是动态的,你可以切换到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
}
}
您的依赖关系应该只注入一次。如果使用不同的请求参数值获取多个请求,会发生什么情况?你每次都得到一台不同的打印机? – Isukthar
是的,实例化的打印机将依赖于请求对象。一旦打印机对象被创建,我们就可以重复使用其他具有相同参数的请求 – sudshekhar
但是您同意,如果使用不同的参数接收到不同的请求,你需要另一台打印机。如果你已经准备好了,你可以在哪里存储它?或者你替换以前的? – Isukthar