Spring 中 ApplicationContext.getBean() 的替代方案

Say*_*yay 3 java spring spring-boot

我在我的应用程序中使用 SpringBoot,并且目前正在使用applicationContext.getBean(beanName,beanClass)它在对它执行操作之前获取我的 bean。我在几个问题中看到不鼓励使用getBean(). 由于我对 Spring 非常陌生,因此我不了解所有最佳实践并且很矛盾。上述链接问题中提出的解决方案可能不适用于我的用例。我应该如何处理这个问题?

@RestController
@RequestMapping("/api")
public class APIHandler {
    @Value("${fromConfig}")
    String fromConfig;

    private ApplicationContext applicationContext;

    public Bot(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @PostMapping(value = "")
    public ResponseEntity post(@RequestBody HandlingClass requestBody) {
        SomeInterface someInterface = applicationContext.getBean(fromConfig, SomeInterface.class);
        someInterface.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个名为SomeInterface定义的接口,如下所示:

public interface SomeInterface {

    void doSomething();
}
Run Code Online (Sandbox Code Playgroud)

我有 2 个类实现了这个接口,称为UseClass1UseClass2。我的配置文件存储了一个带有类的 bean 名称的字符串,我需要在运行时知道它并调用该方法的适当实现。

任何方向将不胜感激。

Nik*_*nko 5

从 Spring 4.3 开始,您可以将所有实现自动装配到由对 beanName <=> beanInstance 组成的 Map 中:

public class APIHandler {

    @Autowired
    private Map<String, SomeInterface> impls;

    public ResponseEntity post(@RequestBody HandlingClass requestBody) {
        String beanName = "..."; // resolve from your requestBody        
        SomeInterface someInterface = impls.get(beanName);
        someInterface.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

假设您有两个实现,如下所示

// qualifier can be omitted, then it will be "UseClass1" by default
@Service("beanName1") 
public class UseClass1 implements SomeInterface { } 

// qualifier can be omitted, then it will be "UseClass2" by default
@Service("beanName2")
public class UseClass2 implements SomeInterface { } 
Run Code Online (Sandbox Code Playgroud)