java - Spring 框架。根据请求参数在运行时注入(inject) bean

标签 java spring spring-boot dependency-injection

假设我们有一个 FileLoader 接口(interface):

public interface FileLoader {

  default String loadFile(String fileId) {
    // Default business logic
    return "Default implementation for FileLoader. Loading file" + fileId;
  }
}

以及不同国家的不同实现:

public class USAFileLoader implements FileLoader {

  @Override
  public String loadFile(String fileId) {
    // ... Specific business logic for USA
    return "USA implementation for FileLoader. Loading file" + fileId;
  }
}

public class FRAFileLoader implements  FileLoader {

  @Override
  public String loadFile(String fileId) {
    // ... Specific business logic for France
    return "France implementation for FileLoader. Loading file" + fileId;
  }
}

我们创建一个端点来加载文件:

import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FileUploadController {

  FileLoader fileLoader;

  @PostMapping("/load/{fileId}/{countryCode}")
  public String loadFile(@PathVariable String fileId, @PathVariable String countryCode) {

    fileLoader = ... // Inject the right loader based on countryCode

    return fileLoader.loadFile(fileId);
  }
}

我怎样才能正确注入(inject) FileLoader在每个请求运行时,基于 countryCode ?我在 Spring 中发现了一个叫做 FactoryBean 的东西这显然可行,但我现在确定它是否是正确的工具,或者这是否是解决此问题的正确方法。另外,我不知道在同时处理请求时注入(inject)的行为会如何。

最佳答案

在这里使用运行时多态性可以做的最好的事情,再添加一个 abstract接口(interface)中的方法 FileLoader对于国家代码

public interface FileLoader {

 default String loadFile(String fileId) {
   // Default business logic
  return "Default implementation for FileLoader. Loading file" + fileId;
 }

 public abstract String getCountryCode();
}

然后在每个实现类中实现它并返回适当的国家代码
public class USAFileLoader implements FileLoader {

  @Override
  public String loadFile(String fileId) {
    // ... Specific business logic for USA
    return "USA implementation for FileLoader. Loading file" + fileId;
   }

  public String getCountryCode(){
   return "USA";
  }
}

然后你可以Autowire所有类型的 bean FileLoader进入 List并调用 loadFile在适当的 bean 上
@RestController
public class FileUploadController {

 @Autowire
 List<FileLoader> fileLoaders;

  @PostMapping("/load/{fileId}/{countryCode}")
  public String loadFile(@PathVariable String fileId, @PathVariable String countryCode) {

return fileLoaders.stream()
                  .filter(f->f.getCountryCode().equlas(countryCode))
                  .findFirst()
                  .map(loader->loader.loadFile(fileId))
                  .orElse(()-> FileLoader.super.loadFile(fileId));  //calling interface default method
  }
} 

关于java - Spring 框架。根据请求参数在运行时注入(inject) bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61432226/

相关文章:

java - 将 "Tutorial View"重叠在标准布局上

java - 如何根据当前秒数获取第二天的第一秒?

spring - Spring Boot 中的计划任务不起作用

java - graphql-java - 如何在 spring boot 中使用订阅?

java - RestController设计之争——Spring Boot REST API

java - 如何刷新java中网络名称的解析?

java - 如何在实体中添加对象列表

spring - Payara/Glassfish 环境中的 Hazelcast + Hibernate + Spring : Type id must be positive! 当前:-202

java - Spring data JPA - 不要在 XML 文件中硬编码密码

spring - 如何在一个端点中使用不同的请求体?