2017-04-05 10 views
0

クラスを作成していて、これにAbstractPrinterオブジェクトがあるとします。 AbstractPrinterは等要求時のSpring MVCインスタンス化オブジェクトの属性

クラスなどHPPrinterFilePrinterController(それが要求属性)に渡されるRequestParamオブジェクトに記載されている使用するプリンタオブジェクトの正確な種類によってサブクラス化されています。

Springを使用して適切なコンクリートプリンタクラスを注入する方法はありますか? 他のすべての依存関係は、@Autowired注釈を使用して挿入されます。これを注入する方法は?

+0

依存関係は1回だけ注入されることになっています。異なるリクエストパラメータ値で多くのリクエストを受け取るとどうなりますか?あなたはいつも別のプリンタを手に入れますか? – Isukthar

+0

はい、インスタンス化されたプリンタはリクエストオブジェクトに依存します。プリンタオブジェクトが作成されると、同じパラメータで他のリクエストに再利用できます – sudshekhar

+0

しかし、異なるパラメータで別のリクエストを受け取った場合、別のプリンタが必要です。あなたはすでにそれを持っている場合はどこに保管することができますか?または前のものを置き換えますか? – Isukthar

答えて

0

作成およびロード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 
    } 
} 
0

AbstractPrinterコンクリートクラスごとに専用のPrinterServiceインスタンスを作成できます。たとえば、あなたがこの工場出荷時のパターンに従う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を呼び出す注入。

コンフィグレーション@ImportPrinterServiceConfigurationを追加することを忘れないでください。

プリンタのリストは、あなたがプロトタイプ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 
    } 
} 
関連する問題