Spring MVC在请求属性上实例化对象

时间:2017-04-05 14:01:23

标签: spring spring-mvc

假设我正在创建一个具有PrinterService对象的AbstractPrinter类。 AbstractPrinter是由HPPrinterFilePrinter等类创建的子类。

传递给我RequestParam的{​​{1}}对象中提到了要使用的确切类型的打印机对象(它是一个请求属性)。

有没有什么方法可以使用Spring注入正确类型的混凝土打印机类? 使用Controller注释注入所有其他依赖项。如何注入这个?

2 个答案:

答案 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
    }
}