在Spring启动中注入许多实现之一

时间:2017-05-04 23:06:26

标签: java spring spring-boot

我们说我有一个处理www.xyz.com/api/<someParam>等请求的控制器。这是我的控制器和我的服务:

@Controller
public class MyController {

   @Autowired MyService service;

   @RequestMapping(value = "/api/{someParam}", method = RequestMethod.GET)  
   public String processRequest(
       @PathVariable("someParam") String someParam) {
          return service.processRequest(someParam);     
   }
}

@Service
public class MyService {
   @Autowired APICaller apiCaller;

   public String processRequest(someParam){
      SomeObj obj = apiCaller.callApi();
      // do something with obj
      // return response;
   }
}

根据URL中传递的参数,我需要调用一些API,对API响应进行一些处理,然后返回它。所有这些API都有不同的处理方式。

让我们说APICaller界面是这样的:

@Service
public interface APICaller {
    public SomeObj callAPI();
}

@Service
public class ABC implements APICaller {
    @Override
    public SomeObj callAPI() {
         // calls some REST api, does some processing to response and returns SomeObj
    }
}

@Service
public class XYZ implements APICaller {
    @Override
    public SomeObj callAPI() {
         // calls some SOAP api, does some processing to response and returns SomeObj
    }
}

因此,如果网址中的参数是&#39; abc&#39;,我需要拨打ABCImpl。如果它是&#39; xyz&#39;,那么我需要拨打XYZImpl。我应该在MyService类中做什么来实例化正确的实现?我可能有多个基于param的实现,而不仅仅是这两个。

感谢。

1 个答案:

答案 0 :(得分:0)

在配置类中定义一个名为的Bean Map。

@SpringBootApplication
public class Application {

    @Bean
    ABC abc() {
        return new ABC();
    }

    @Bean
    XYZ xyz() {
        return new XYZ();
    }

    @Bean(name="apis")
    Map<String, APICaller> apis() {
        Map<String, APICaller> map = new HashMap<>();
        map.put("xmz", xyz());
        map.put("abc", abc());
        return map;
    }
}

然后按如下方式注入:

@Service
public class MyService {
      @Resource(name="apis")
      Map<String, APICaller> apis;

      public String processRequest(String param){
         apis.get(param).callApi();
         // do required null checks before calling callApi()
         // do something with obj
         // return response;
      }
}

<强>更新

根据您的评论,如果您仍然想要自动连接APICaller的依赖关系,那么这就是如何使用@Bean

@Bean
ABC abc(DependancyBean1 bean2) {
    return new ABC(bean1);
}

@Bean
XYZ xyz(DependancyBean2 bean2) {
    return new XYZ(bean2);
}