@Resource、@Autowired、@Qualifier区别与使用,以及bean name 的默认生成规则。

前言

一、注解区别

1. @Autowired

@Autowired 是Spring的注解。通过 byType 的方式去注入,仅有一个required属性,默认为true,默认装配规则如下:

  1. 先通过类型查找,找到只有一个则装配,找不到则抛出异常,
  2. 如果找到多个,则从中按照名字查找,找到则装配,找不到则抛出异常

当required为false时,最终找不到则忽略不装配。

2. @Qualifier

@Qualifier是Spring的注解。字面含义为合格者,按名称注入。用于装配时有多个候选bean时通过指定一个标识来解决冲突,仅有一个默认value属性,作为标识,定义bean时通过添加@Qualifier(“xxx”)指定。每一个bean都有一个自身名称标识的Qualifier。

一般当出现两个及以上bean时,不知道要注入哪个,作为@Autowired()的修饰用。

  1. 当value不指定时,这个标识为"",而不是bean的名称或者作用的属性名称。
  2. 当通过类型找到一个时,但是不匹配Qualifier指定标识,也会抛出异常(它不仅解决冲突,甚至有点矫枉过正)

3. @Resource

@Resource 是 J2EE 的注解。以通过 byNamebyType 的方式注入。

默认先按 byName的方式进行匹配,如果匹配不到,再按 byType的方式进行匹配。用与资源(通常是JNDI)的注入。 Spring对其进行了支持。

装配规则:

  1. 如果指定了name属性,则按照name查找,找到且类型匹配则装配,否则配抛出异常
  2. 如果指定了name和type属性,则按照name和type精确查找,找到则装配,找不到抛出异常
  3. 如果仅指定了type属性,则按照type查找,如果只找到一个则装配,否则抛出异常
  4. 如果name和type都没有指定,则默认按照作用的属性名字查找,找到则装配,找不到则按照类型找,找到一个则装配,找不到或者找到多个抛出异常

注意 : 如果不指定name 和 type。先按 byName (其name为 注入的自定义的名称,首字母大写的变为小写,后面为驼峰命名规则)。 如果匹配不到,再按 byType的方式进行匹配。

如果想减少对 Spring 的依赖建议使用 @Resource 方法。

二、使用三个注解

我拿我之前写的需求过来写一下,我接收三种不同的数据,需要放在三个堵塞队列中,然后再使用三个线程池去消费。我想把三个堵塞队列写在一个配置类中。如下:

BlockingQueueConfig.java

package com.uniview.airport.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 三个堵塞队列,分别对应三个告警类型的传递
 */
@Configuration
public class BlockingQueueConfig {

    /**
     *  飞机开关车门
     * @return
     */
    @Bean(name = "BlockingOpenAndCloseDoor")
    public BlockingQueue getBlockingQueueOpenAndCloseDoor(){
        return new LinkedBlockingQueue(2000);
    }

    /**
     *飞机撤侨
     * @return
     */
    @Bean(name = "BlockingQueueEvacuees")
    public BlockingQueue getBlockingQueueEvacuees(){
        return new LinkedBlockingQueue(2000);
    }

    /**
     * 飞机入离位
     * @return
     */
    @Bean(name = "BlockingQueueEntryAndExit")
    public BlockingQueue getBlockingQueueEntryAndExit(){
        return new LinkedBlockingQueue(2000);
    }
}

两种实现方式

@Slf4j
@RestController
@RequestMapping("objIdentify")
public class AlarmController {
    
    /**
     *  飞机开关舱门
     */
    @Resource(name = "BlockingOpenAndCloseDoor")
    private BlockingQueue blockingOpenAndCloseDoor;

    /**
     *  飞机撤侨
     */
    @Qualifier(value = "BlockingQueueEvacuees")
    @Autowired
    private BlockingQueue blockingQueueEvacuees;

    /**
     * 飞机入离位
     */
    @Resource(name = "BlockingQueueEntryAndExit")
    private BlockingQueue blockingQueueEntryAndExit;
}

成功运行,不报错。

三、bean name默认生成规则

在SSM 或者 springboot 项目中,会用到依赖注入。其前提是将这个类配置成bean并加入到spring容器中,也就是 IOC容器。

现在一般都是用配置式和注解式来将bean装配到容器中。

一般都使用注解 @Controller 、@Service、 @Repository、@Component、@Configuration 等注解来标注在类上,一般用 @Bean 标注方法上(一般在配置类上)。

那他们的 bean name 是多少呢????

在Spring中,当我们配置一个bean的时候,可以不指定name,这样的话,Spring会生成一个默认的beanName,生成规则:原以为只是简单的将类名首字母小写,后面为驼峰命名规则,Spring官方文档还指出——当类名的首字母和第二个字母是大写的时候,将采用原始的类名作为beanName。

例如:

  1. SysConfig - sysConfig,Tools - tools。
  2. RBACUserLog - RBACUserLog,RBACUser - RBACUser,RBACRole - RBACRole。

spring文档原文如下:

With component scanning in the classpath, Spring generates bean names for unnamed components, following the rules above: essentially, taking the simple class name and turning its initial character to lower-case. However, in the (unusual) special case when there is more than one character and both the first and second characters are upper case, the original casing gets preserved. These are the same rules as defined by java.beans.Introspector.decapitalize (which Spring is using here).

大概意思就是说spring在给未命名的组件生成bean name的时候,采用简单的类名并将其初始字符转换为小写。但在特殊情况下,当第一个和第二个字符都是大写的时候,保留原始的形式。而spring使用的就是在java.beans.Introspector类中的decapitalize方法实现的。

Bean注解括号里面的字符串就是bean的名字,也可以不加,默认bean的名字是@Bean注解所对应的方法的方法名

  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java冯坚持

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值