@Autowired是根据类型进行自动装配的。如果当spring上下文中存在不止一个A类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在A类型的bean,而且我们又使用A类型,也会抛出BeanCreationException异常。
针对存在多个A类型的Bean,我们可以联合使用@Qualifier和@Autowired来解决这些问题。
英文文档在这里
例如
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.yq.demo.service.UserService' available: expected single matching bean but found 2: myUserServiceImpl,userServiceImpl
at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
我们的service接口是
public interface UserService {
public long userCount();
public String showSpecificClassName();
public List<User> getAllUser();
public User addUser(User user);
public void delUser(Integer id);
public User updateUser(User user);
public User getUserByName(String username);
public User getUserByID(Integer id);
}
我们有两个实现类,分别是MyUserServiceImpl和UserServiceImpl
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserJpaRepository userJpaRepo;
private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);
@Override
public long userCount(){
return userJpaRepo.count();
}
@Override
public String showSpecificClassName() {
String clsName = this.getClass().getCanonicalName();
log.info("impl class is " + clsName);
return clsName;
}
...
@Service
public class MyUserServiceImpl implements UserService {
@Autowired
private UserJpaRepository userJpaRepo;
private static final Logger log = LoggerFactory.getLogger(MyUserServiceImpl.class);
@Override
public long userCount(){
return userJpaRepo.count();
}
@Override
public String showSpecificClassName() {
String clsName = this.getClass().getCanonicalName();
log.info("impl class is " + clsName);
return clsName;
}
然后我们在其他地方,如controller中这样写
@Controller
@RequestMapping(path="/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(value = "/testAutowired", produces = "application/json;charset=UTF-8")
public @ResponseBody String testAutowired (@RequestParam String name) {
String name1 = userService.showSpecificClassName();
return name1;
}
当我们启动程序时就会报错,因为有两个UserService的实现类。程序不知道该选择那个。 这时可以使用Qualifier 来解决唯一性问题
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
具体代码在这里,欢迎加星和fork。