Spring学习笔记之 @Qualifier和@Primary的区别

学习蚂蚁课堂关于Spring源码的课程:@Qualifier和@Primary的区别

假设一个接口下有两个实现类,这时候使用@Autowired获取的时候会有什么问题?怎么解决?
* UserService
* UserService001Impl
* UserService002Impl
*
* @Autowired
* UserService
*
* @Autowired默认的情况下使用 类型查找

会报错:

No qualifying bean of type ‘com.jiyu.v4.service.UserService’ available: expected single matching bean but found 2: userService001Impl,userService002Impl

代码:

(1)配置类:

package com.jiyu.v4.config;

import com.jiyu.v4.ServiceImpl.OrderServiceImpl;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * 别忘了扫包,不然无法注入bean
 */
@ComponentScan("com.jiyu.v4")
@Configuration
public class MyConfig {
}

(2)UserService接口

package com.jiyu.v4.service;

/**
 * @author jiyu
 * @date 2020/11/07 10:12
 *
 * 假设一个接口下有两个实现类,这时候使用@Autowired获取的时候
 * UserService
 * UserService001Impl
 * UserService002Impl
 *
 *  @Autowired
 *  UserService
 *
 * 因为@Autowired默认的情况下使用 类型查找
 * SpringBoot 多数据源 设置默认的时候(优先级)
 */
public interface UserService {
    void add();
}

(3)

package com.jiyu.v4.ServiceImpl;

import com.jiyu.v4.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * @author jiyu
 * @date 2020/11/07 10:23
 */
@Component
public class OrderServiceImpl {


     @Autowired
    // @Qualifier("userService001Impl")
   // @Resource(name = "userService001Impl")
    private UserService userService;

    public void add(){
        System.out.println("11");
        userService.add();
    }

}

(4)

package com.jiyu.v4.ServiceImpl;

import com.jiyu.v4.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * @author jiyu
 * @date 2020/11/07 10:14
 */

@Service
@Primary
public class UserService001Impl implements UserService {
    public void add() {
        System.out.println("UserService001Impl");
    }
}

(5)

package com.jiyu.v4.ServiceImpl;

import com.jiyu.v4.service.UserService;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

/**
 * @author jiyu
 * @date 2020/11/07 10:14
 */
@Service
public class UserService002Impl implements UserService {
    public void add() {
        System.out.println("UserService002Impl");
    }
}

(6)

package com.jiyu.v4;

import com.jiyu.v4.config.MyConfig;
import com.jiyu.v4.ServiceImpl.OrderServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author jiyu
 * @date 2020/11/07 10:46
 */
public class V4Test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MyConfig.class);

        OrderServiceImpl orderServiceImpl = (OrderServiceImpl) annotationConfigApplicationContext.getBean("orderServiceImpl");
        orderServiceImpl.add();
    }
}

解决办法是:
1、
使用**@Resource**注解指定需要注入的实现类

@Resource(name = "userService001Impl")
 private UserService userService;

2、
使用**@Qualifier**注解指定需要注入的实现类

 @Autowired
 @Qualifier("userService001Impl")
  private UserService userService;

3、在UserService接口的两个实现类中我要需要注入的那一个加上**@Primary**注解指定优先级。

//OrderServiceImpl类:

 @Autowired
 private UserService userService;
//UserService001Impl 类:
@Service
@Primary
public class UserService001Impl implements UserService {
    public void add() {
        System.out.println("UserService001Impl");
    }
}

@Qualifier 和 @Primary的区别就是前者需要指定名字,而且使用的位置不一样。

需要注意的地方:

1、

照着敲报了一个错:NoSuchBeanDefinitionException: No bean named ‘orderServiceImpl’ available
没有这个bean?

原因是配置类中没有加上扫包注解:@ComponentScan(“com.jiyu.v4”)

2、

即使使用了 @Qualifier和@Resource注解还是报错

No qualifying bean of type ‘com.jiyu.v4.service.UserService’ available: expected single matching bean but found 2: userService001Impl,userService002Impl

原因是:bean名我使用了和类名相同的名字所以注入失败了,
应该是这样:首字母小写
@Qualifier(“userService001Impl”)
@Resource(name = “userService001Impl”)

这里bean名有一个规则: bean 名就要看被注解的类名, 如果类名开头是两个或两个大写字母以上, bean 名同类名完全一致;
如果开头只有一个大写字母, bean 名是类名首字母小写版.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值