使用Autowired和Qualifier解决多个相同类型的bean如何共存的问题

@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 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。

你可能感兴趣的:(springboot,bean,Autowired,Qualifier,Java)