@Primary ,@Qualifier ,@Autowired ,@Resource作用与区别

首先阐述 @Autowired 和 @Resource 的区别

@Resource 是JDK自带的注解 可以按名称注入也可以按类型注入,默认是按名称注入,没有显式指定名称时,在spring容器中匹配与需要注入的bean属性名相同的bean,如果还不同,@Resource会找到一个主类型匹配而不是一个特定的命名bean
@Autowired 由spring 提供 ,默认按类型注入,也可结合@Qualifier() 实现按名称注入

需要注意的是 以@Bean方式注入对象时,@Resource 按名称注入,是按声明的方法名注入的
@Autowired 结合 @Qualifier() 实现按名称注入时,是按@Qualifier() 定义的名称注入的

@Primary 当需要注入多个同类型的bean时,选择其中一个为优先注入对象,并且同类型对象只能选择一个,超过一个时则启动报错,提示信息就是你选择了多个bean为优先注入对象

@Qualifier() 你可以为每个注入的bean起个不同的名字,结合@Autowired 实现按名称注入

示例:
@Autowired 结合 @Qualifier() 实现按名称注入
首先定义一个需要注入的对象

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class UserInfo {
    private String username;
    private String password;
}

然后定义一个config类,注入两个UserInfo,利用 @Qualifier() 声明两个不同的bean

import com.example.demo.entities.UserInfo;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserInfoConfig {

    @Bean
    @Qualifier("zhangsan")
    public UserInfo userInfo() {
        UserInfo userInfo = UserInfo.builder().username("zhangsan").password("123456").build();
        return userInfo;
    }

    @Bean
    @Qualifier("lisi")
    public UserInfo userInfo1() {
        UserInfo userInfo = UserInfo.builder().username("lisi").password("123456").build();
        return userInfo;
    }

}

controller 层注入 zhangsan这个对象

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    @Qualifier("zhangsan")
    private UserInfo userInfo;

    @GetMapping("/getUserInfo")
    public UserInfo getUserInfo() {
        return userInfo;
    }
}

返回结果为

{
    "username": "zhangsan",
    "password": "123456"
}

我们再注入lisi这个对象

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    @Qualifier("lisi")
    private UserInfo userInfo;

    @GetMapping("/getUserInfo")
    public UserInfo getUserInfo() {
        return userInfo;
    }
}

返回结果

{
    "username": "lisi",
    "password": "123456"
}

接下来,我们测一下@Primary 看是否实现优先注入,修改config类

@Configuration
public class UserInfoConfig {

    @Bean
    @Primary
    public UserInfo userInfo() {
        UserInfo userInfo = UserInfo.builder().username("zhangsan").password("123456").build();
        return userInfo;
    }

    @Bean
    public UserInfo userInfo1() {
        UserInfo userInfo = UserInfo.builder().username("lisi").password("123456").build();
        return userInfo;
    }
}

controller 层 直接用 @Autowired 注入

@RequestMapping("/user")
@RestController
public class UserController {

    @Autowired
    private UserInfo userInfo;

    @GetMapping("/getUserInfo")
    public UserInfo getUserInfo() {
        return userInfo;
    }
}

返回结果,没毛病

{
    "username": "zhangsan",
    "password": "123456"
}

我们再验证 lisi这个对象

@Configuration
public class UserInfoConfig {

    @Bean
    public UserInfo userInfo() {
        UserInfo userInfo = UserInfo.builder().username("zhangsan").password("123456").build();
        return userInfo;
    }

    @Bean
    @Primary
    public UserInfo userInfo1() {
        UserInfo userInfo = UserInfo.builder().username("lisi").password("123456").build();
        return userInfo;
    }
}

返回结果,没得毛病

{
    "username": "lisi",
    "password": "123456"
}

接下来我们再测,@Resource 的按名称注入,看是否是按定义的方法名注入的

config类

@Configuration
public class UserInfoConfig {

    @Bean
    public UserInfo userInfo() {
        UserInfo userInfo = UserInfo.builder().username("zhangsan").password("123456").build();
        return userInfo;
    }

    @Bean
    public UserInfo userInfo1() {
        UserInfo userInfo = UserInfo.builder().username("lisi").password("123456").build();
        return userInfo;
    }
}

controller 层

@RequestMapping("/user")
@RestController
public class UserController {

    @Resource(name = "userInfo")
    private UserInfo userInfo;

    @GetMapping("/getUserInfo")
    public UserInfo getUserInfo() {
        return userInfo;
    }
}

返回结果

{
    "username": "zhangsan",
    "password": "123456"
}

修改@Resource(name = “userInfo1”) 注入第二个方法名
返回结果,没毛病哈

{
    "username": "lisi",
    "password": "123456"
}
### 回答1: Spring中的@Primary和@Qualifier是两个常用的注解,用于解决当有多个类型bean需要注入时的歧义问题。 @Primary注解用在bean的定义上,表示该bean是优先选择的bean。当有多个类型bean需要注入时,Spring会优先选择被@Primary注解标记的bean作为注入的对象。 @Qualifier注解用在注入点上,可以和@Autowired、@Resource等注解一起使用,用来指定具体要注入的bean的名称。通过在@Qualifier中指定bean的名称,可以明确告诉Spring要选择哪个bean进行注入。 举个例子来说明,假设有一个接口类型bean,下面有两个实现类A和B都实现了这个接口,并且都被Spring管理。 当我们在其他地方需要注入这个接口类型bean时,如果不使用@Qualifier和@Primary,Spring会产生歧义,无法确定注入哪个实现类的对象。 使用@Primary注解,我们可以在实现类A上标注@Primary,表示A是优先选择的bean。 当需要注入接口类型bean时,Spring会自动选择A作为注入的对象。 使用@Qualifier注解,我们可以在注入点上标注@Qualifier,然后在@Qualifier中指定具体要注入的bean的名称。 比如,可以使用@Qualifier("beanA")明确指定要注入的bean是A。 以上就是@Primary和@Qualifier的基本用法和含义,通过使用这两个注解可以很方便地解决多个类型bean的注入问题。 ### 回答2: spring中的@Primary和@Qualifier是依赖注入中的两个注解。 @Primary注解用于标注一个类为首选的bean。当有多个类型相同的bean存在时,spring将会优先选择被@Primary注解标注的bean进行注入。 @Qualifier注解可以与@Autowired一起使用,用于解决存在多个类型相同的bean时的歧义性。通过为@Autowired指定@Qualifier注解的value属性,可以指定具体注入哪个bean。 例如,假设我们有一个接口Person,有两个实现类:Student和Teacher。如果我们在Spring配置文件中同时注册了这两个bean,那么在注入Person类型的依赖时就会有歧义。此时,我们可以使用@Primary注解为其中一个实现类标注为首选bean。这样,在需要注入Person类型的地方,spring就会优先选择被@Primary注解标注的实现类进行注入。 另一种情况是,如果我们不想使用@Primary注解来标注首选bean,而是希望根据特定的条件进行选择注入,就可以使用@Qualifier注解。@Qualifier注解需要与@Autowired注解一起使用,通过指定value属性来指定注入哪个bean。比如,我们可以在@Autowired注解后添加@Qualifier("student")来指定注入的是Student类型bean。 通过@Primary和@Qualifier注解,我们可以在存在多个类型相同的bean时,精确控制注入的对象,避免歧义性。 ### 回答3: Spring是一个开源的Java框架,提供了依赖注入(Dependency Injection)的功能。在Spring中,我们可以使用@Primary和@Qualifier注解来处理多个相同类型的实例。 @Primary注解用于标识在多个相同类型Bean中,哪个Bean应该作为首选的Bean。当我们不使用@Qualifier注解指定具体的Bean时,Spring会自动选择使用带有@Primary注解的Bean。例如,当我们有多个实现了同一个接口的类时,通过使用@Primary注解,我们可以指定一个类作为主要实现。 @Qualifier注解用于在多个相同类型Bean中选择特定的Bean。当我们有多个相同类型Bean需要注入时,在使用@Autowired或@Inject注入时,我们可以使用@Qualifier注解指定具体的Bean。@Qualifier注解的参数可以是Bean的名字或者是自定义的标识符。 举个例子来说,假设我们有一个接口Animal,有两个实现类Dog和Cat。如果我们希望将Cat作为首选的实现类,我们可以在Cat类上使用@Primary注解。如果有一个需要注入Animal类型的类,但我们想注入Dog,我们可以在注入的地方使用@Qualifier("dog")注解来指定具体的Bean。 总之,@Primary注解用于标识首选的Bean,@Qualifier注解用于指定特定的Bean。它们可以一起使用来处理多个相同类型的实例,使得依赖注入更加灵活和精确。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值