一、接口、实现类关系
- 接口:MoreImplService
- 抽象类:AbstractMoreImplTestService
- 实现类:MoreImplTest1ServiceImpl、MoreImplTest2ServiceImpl
二、直接使用实现类接收Bean
- 实现类 MoreImplTest1ServiceImpl
//@Component("moreImplTest1Service")
@Component
public class MoreImplTest1ServiceImpl extends AbstractMoreImplTestService {
@Override
public String test() {
System.out.println("我是test1");
return "我是test1";
}
}
- 实现类 MoreImplTest2ServiceImpl
//@Component("moreImplTest2Service")
@Component
public class MoreImplTest2ServiceImpl extends AbstractMoreImplTestService {
@Override
public String test() {
System.out.println("我是test2");
return "我是test2";
}
}
- 调用注入类:MoreImplController
@RestController
@RequestMapping("/moreimpl")
public class MoreImplController {
private final Map<Integer, MoreImplService> moreImplServiceMap = new HashMap<>();
private final HttpClientProvider httpClientProvider;
public MoreImplController(MoreImplTest1ServiceImpl moreImplTest1Service,
MoreImplTest1ServiceImpl moreImplTest2Service,
HttpClientProvider httpClientProvider) {
this.httpClientProvider = httpClientProvider;
moreImplServiceMap.put(1, moreImplTest1Service);
moreImplServiceMap.put(2, moreImplTest2Service);
}
@GetMapping
public void moreImplTestNb(@RequestParam String from) throws IOException {
MoreImplService moreImplService = moreImplServiceMap.get(0);
if ("1".equals(from)) {
moreImplService = moreImplServiceMap.get(1);
}
moreImplService.test();
}
}
以上在调用注入类中直接使用实现类来接受他们各自的Bean。
三、使用Bean别名,且使用接口来接收
- 实现类 MoreImplTest1ServiceImpl
@Component("moreImplTest1Service")
//@Component
public class MoreImplTest1AServiceImpl extends AbstractMoreImplTestService {
@Override
public String test() {
System.out.println("我是test2");
return "我是test2";
}
}
- 实现类 MoreImplTest2ServiceImpl
@Component("moreImplTest2Service")
//@Component
public class MoreImplTest2ServiceImpl extends AbstractMoreImplTestService {
@Override
public String test() {
System.out.println("我是test2");
return "我是test2";
}
}
- 调用注入类 MoreImplController
@RestController
@RequestMapping("/moreimpl")
public class MoreImplController {
private final Map<Integer, MoreImplService> moreImplServiceMap = new HashMap<>();
private final HttpClientProvider httpClientProvider;
public MoreImplController(MoreImplService moreImplTest1Service,
MoreImplService moreImplTest2Service,
HttpClientProvider httpClientProvider) {
this.httpClientProvider = httpClientProvider;
moreImplServiceMap.put(1, moreImplTest1Service);
moreImplServiceMap.put(2, moreImplTest2Service);
}
@GetMapping
public void moreImplTestNb(@RequestParam String from) throws IOException {
MoreImplService moreImplService = moreImplServiceMap.get(0);
if ("1".equals(from)) {
moreImplService = moreImplServiceMap.get(1);
}
moreImplService.test();
test();
}
}
以上是调用注入类通过接口接受Bean,且Bean是通过别名注入的。
四、小总结
- 直接使用实现类接收Bean看起来不优雅,而且在低版本Spring可能会出现注入错误的情况,目前我使用的版本没有复现。
- 直接Bean别名和接口接收,代码很优雅,而且类是通过name去注入,可以一定程度避免依赖循环问题。
- 小tips:接口多个实现类时,可以直接使用List<?>来接收所以实现类,当时我们需要根据我们的规则给List排序,不然自己都不在使用哪个实现类。Spring源码是怎么对多个实现类的List接收顺序是怎么样的,感兴趣的小伙伴可以去了解一下。