2017-04-05 77 views
0

假设我创建了一个PrinterService类,该类具有AbstractPrinter对象。 AbstractPrinter由类,如HPPrinterFilePrinterSpring MVC根据请求实例化对象属性

确切种类打印机对象的情况下使用在传递给我Controller(它是一个请求属性)RequestParam对象被提到的子类。

有什么办法可以使用Spring注入合适的具体打印机类? 所有其他依赖项均使用@Autowired注释注入。如何注入这个?

+0

您的依赖关系应该只注入一次。如果使用不同的请求参数值获取多个请求,会发生什么情况?你每次都得到一台不同的打印机? – Isukthar

+0

是的,实例化的打印机将依赖于请求对象。一旦打印机对象被创建,我们就可以重复使用其他具有相同参数的请求 – sudshekhar

+0

但是您同意,如果使用不同的参数接收到不同的请求,你需要另一台打印机。如果你已经准备好了,你可以在哪里存储它?或者你替换以前的? – Isukthar

回答

0

您可以创建和如下图所示的容器启动时加载工厂AbstractPrinter对象和动态调用相应的AbstractPrinterprint()(或您自己的方法)基于输入参数(来自控制器)到服务。

在为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 
    } 
} 
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用正确的打印机类型。

不要忘记在您的配置@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 
    } 
}