2017-04-05 48 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 
    } 
}