基于请求端点/请求参数的运行时Spring Boot注入Bean

时间:2018-11-01 08:46:32

标签: java spring spring-boot

我有一个具有两个实现的接口,我想有条件地将两个实现中的任何一个注入到Spring Boot服务中。

重点是应根据请求消息(JSON映射到POJO)选择合格的实现。

我的搜索使我实现了一个FactoryBean来控制在这两种实现之间的选择,并保持工厂告诉spring这些bean不是单例(通过为isSingleton方法返回false)。

但是,如果这是正确的方法,我仍然不确定如何获取请求消息以进行检查并返回正确的bean。

您能告诉我我是否在正确的方向上努力?

=============

更新

我不想污染我的代码并处理管理服务与服务中依赖项实现之间的关系。

考虑到我将来需要处理更多的实现,我需要我的服务仅关心它的责任。

  1. 我需要我的服务仅具有通用接口的一个引用,并以抽象的方式处理它。
  2. 我需要找到一种基于 spring的方式,以便根据源自请求本身的条件为每个请求选择正确的实现 ,并将其注入服务。

3 个答案:

答案 0 :(得分:0)

您可以@Autowire在控制器中同时使用两个bean,并根据请求决定返回哪个bean。

考虑以下界面:

public interface MyInterface { ... }

示例配置:

@Configuration
public class MyConfig {

    @Bean("first")
    public MyInterface firstBean() { ... }

    @Bean("second")
    public MyInterface secondBean() { ... }

}

示例控制器:

@RestController
public class MyController {

    @Autowire
    @Qualifier("first")
    public MyInterface first;

    @Autowire
    @Qualifier("second")
    public MyInterface second;

    @GetMapping
    public MyInterface doStuff(@RequestBody body) {
        if(shouldReturnFirst(body)){
            return first;
        } else {
            return second;
        }
    } 

}

请注意,您极有可能不会这样做,而应该使用单一服务,例如MyService

@Component
public class MyService {

    public MyInterface doStuff(body) {
        if(shouldReturnFirst(body)){
            // build your response here
        } else {
            // build your response here
        }
    }

}

只需从控制器委派服务即可

@GetMapping
public MyInterface doStuff(@RequestBody body) {
    return myService.doStuff(body);
} 

答案 1 :(得分:0)

一个选择是同时注入两个bean并有条件地选择所需的bean。您可以将实现相同接口的类自动装配到Map中。

下面的示例使用工厂类来隐藏条件检查。

@Component("type1")
public class Type1 implements SomeInterface{}

@Component("type2")
public class Type2 implements SomeInterface{}

@Component
public class MyTypeFactory {

  @Autowired
  private Map<String, SomeInterface> typesMap;

  public SomeInterface getInstance(String condition){
    return typesMap.get(condition);
  }

}

@Component
public class MyService {
  @Autowired
  private MyTypeFactory factory;

  public void method(String input){
     factory.getInstance(input).callRequiredMethod();
  }

}

答案 2 :(得分:0)