前言
在SpringBoot项目中,如果一个Service层接口,有多种实现方式,我们应该如何去选择正确的实现类去注入呢?
废话不多说,看例子,上代码:
// TestService.java 定义接口
public interface TestService {
void testMethod();
}
// TestServiceImpl1.java 实现类一
@Service
public class TestServiceImpl1 implements TestService {
protected static final Logger logger = LoggerFactory.getLogger(TencentCosUtils.class);
@Override
public void testMethod() {
logger.info("TestServiceImpl1");
}
}
// TestServiceImpl2.java 实现类二
@Service
public class TestServiceImpl2 implements TestService {
protected static final Logger logger = LoggerFactory.getLogger(TencentCosUtils.class);
@Override
public void testMethod() {
logger.info("TestServiceImpl2");
}
}
当我们遇到这种情况时,SpringBoot项目扫描到了多个实现类,如果直接注入,会直接报异常:
那我们该如何去选择相应的实现类呢?
使用@Qualifier
注解选择实现类
我们在调用时,通过使用@Qualifier
来指定实现类,来实现对指定类的依赖注入:
@Autowired
@Qualifier("testServiceImpl1")
TestService testService;
@GetMapping("test")
public R test(){
testService.testMethod();
return R.ok();
}
访问控制器,发现在控制台中成功的输出了testServiceImpl1。
使用@Primary
注解在指定默认实现类
在SpringBoot项目中,我们还可以通过在实现类中添加@Primary
注解来使其变成一个主要实现类,这样在SpringBoot扫描到多个实现类时,会自动选择主要实现类进行注入。
// TestServiceImpl2.java
@Service
@Primary
public class TestServiceImpl2 implements TestService {
protected static final Logger logger = LoggerFactory.getLogger(TencentCosUtils.class);
@Override
public void testMethod() {
logger.info("TestServiceImpl2");
}
}
@Autowired
TestService testService;
@GetMapping("test")
public R test(){
testService.testMethod();
return R.ok();
}
访问控制器,发现在控制台中成功的输出了testServiceImpl2。
@Qualifier
VS @Primary
既然两种方式都可以实现在多个实现类中自动注入,那他们的区别是什么呢?
@Qualifier
是指定实现类,在每次注入是都要指定我们需要注入的实现类。@Primary
是设置首选实现类,在注入时发现了多个实现类,定义了首选项。@Qualifier
的优先级高于@Primary
,如果定义了指定实现类,那么即使定义了首选实现类,也会自动注入到指定实现类中。