使用@Autowired、@Qualifier、@Primary注解自动装配组件

1.@Autowired、@Qualifier、@Primary注解

1.1.@Autowired注解

@Autowired注解可以对类成员变量、方法和构造函数进行标注,完成自动装配的工作。

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

	boolean required() default true;
}

@Autowired注解说明:

  1. @Autowired注解默认是优先按照类型去容器中找对应的组件,若找到则就赋值,相当于是调用了如下这个方法:
    applicationContext.getBean(类名.class);
    
  2. 如果找到多个相同类型的组件,那么是将属性名称作为组件的id,到IOC容器中进行查找,这时就相当于是调用了如下这个方法:
    applicationContext.getBean("组件的id");
    

1.2.@Qualifier注解

@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,那么就需要配合@Qualifier注解来使用了。

@Qualifier注解的源码,如下所示:

package org.springframework.beans.factory.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {

	String value() default "";

}

1.3.@Primary注解

在Spring中使用注解时,常常会使用到@Autowired这个注解,它默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口而言,可能会有几种不同的实现类,而在默认只会采取其中一种实现的情况下,就可以使用@Primary注解来标注优先使用哪一个实现类。

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {

}

2.自动装配

Spring组件的自动装配就是Spring利用依赖注入,也就是我们通常所说的DI,完成对IOC容器中各个组件的依赖关系赋值。

3.程序案例

3.1.测试@Autowired注解

3.1.1.测试1

创建BookDao、BookService、BookServiceImpl和BookController

  • BookDao
    package com.tianxia.springannotation.dao;
    
    import org.springframework.stereotype.Repository;
    
    /**
     * BookDao
     * @author liqb
     * @date 2023-04-21 16:37
     **/
    // 名字默认是类名首字母小写
    @Repository
    public class BookDao {
    }
    
  • BookService
    package com.tianxia.springannotation.service;
    
    /**
     * BookService
     * @author liqb
     * @date 2023-04-21 16:38
     **/
    public interface BookService {
    }
    
    
  • BookServiceImpl
    package com.tianxia.springannotation.service.impl;
    
    import com.tianxia.springannotation.dao.BookDao;
    import com.tianxia.springannotation.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * BookServiceImpl
     * @author liqb
     * @date 2023-04-21 16:38
     **/
    @Service
    public class BookServiceImpl implements BookService {
    
        @Autowired
        private BookDao bookDao;
    
        /**
         * 打印方法
         * @author liqb
         * @date 2023-05-06 13:09
         */
        public void print() {
            System.out.println(bookDao);
        }
        
        @Override
        public String toString() {
            return "BookService [bookDao=" + bookDao + "]";
        }
    }
    
  • BookController
    package com.tianxia.springannotation.controller;
    
    import com.tianxia.springannotation.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    /**
     * BookController
     * @author liqb
     * @date 2023-04-21 16:39
     **/
    @Controller
    public class BookController {
        
        @Autowired
        private BookService bookService;
    }
    

为了更好的看到效果,在项目的config包下创建MainConfigOfAutowired配置类,如下所示:

package com.tianxia.springannotation.config;

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

/**
 * 配置类
 * @author liqb
 * @date 2023-05-06 13:11
 **/
@Configuration
@ComponentScan({"com.tianxia.springannotation.service", "com.tianxia.springannotation.dao", "com.tianxia.springannotation.controller"})
public class MainConfigOfAutowired {
}

运行测试方法,输出结果如下所示:

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-06 13:14
 */
@Test
public void test01() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    BookService bookService = applicationContext.getBean(BookService.class);
    System.out.println(bookService);
    
    BookDao bookDao = applicationContext.getBean(BookDao.class);
		System.out.println(bookDao);

    applicationContext.close();
}

在这里插入图片描述

BookService类中使用@Autowired注解注入的BookDao对象和直接从IOC容器中获取的BookDao对象是同一个对象

3.1.2.测试2

在Spring容器中存在对多个BookDao对象,那么这时又该如何处理

对BookDao类进行改造,为其加上一个lable字段,并为其赋一个默认值,如下所示。

package com.tianxia.springannotation.dao;

import org.springframework.stereotype.Repository;

/**
 * BookDao
 * @author liqb
 * @date 2023-04-21 16:37
 **/
// 名字默认是类名首字母小写
@Repository
public class BookDao {

    private String lable = "1";

    public String getLable() {
        return lable;
    }

    public void setLable(String lable) {
        this.lable = lable;
    }

    @Override
    public String toString() {
        return "BookDao [lable=" + lable + "]";
    }
}

在MainConfigOfAutowired配置类中注入一个BookDao对象,并且显示指定该对象在IOC容器中的bean的名称为bookDao2,并还为该对象的lable字段赋值为2

package com.tianxia.springannotation.config;

import com.tianxia.springannotation.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类
 * @author liqb
 * @date 2023-05-06 13:11
 **/
@Configuration
@ComponentScan({"com.tianxia.springannotation.service", "com.tianxia.springannotation.dao", "com.tianxia.springannotation.controller"})
public class MainConfigOfAutowired {

    /**
     * 注入bookDao对象
     * @author liqb
     * @date 2023-05-06 13:27
     * @return
     */
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao();
        bookDao.setLable("2");
        return bookDao;
    }
}

运行测试方法,输出结果如下所示:

/**
 * 测试方法
 * @author liqb
 * @date 2023-05-06 13:14
 */
@Test
public void test01() {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);

    BookService bookService = applicationContext.getBean(BookService.class);
    System.out.println(bookService);

    applicationContext.close();
}

在这里插入图片描述

结果信息输出了lable=1,说明,@Autowired注解默认是优先按照类型去容器中找对应的组件,找到就赋值;如果找到多个相同类型的组件,那么再将属性的名称作为组件的id,到IOC容器中进行查找

让@Autowired注解装配bookDao2

将BookService类中的bookDao属性的名称全部修改为bookDao2即可,如下所示:

package com.tianxia.springannotation.service.impl;

import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * BookServiceImpl
 * @author liqb
 * @date 2023-04-21 16:38
 **/
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookDao bookDao2;

    /**
     * 打印方法
     * @author liqb
     * @date 2023-05-06 13:09
     */
    public void print() {
        System.out.println(bookDao2);
    }
    
    @Override
    public String toString() {
        return "BookService [bookDao=" + bookDao2 + "]";
    }
}

运行测试方法,输出结果如下所示:

在这里插入图片描述

结论:@Autowired注解默认是优先按照类型去容器中找对应的组件,找到就赋值;如果找到多个相同类型的组件,那么再将属性的名称作为组件的id,到IOC容器中进行查找。

3.1.3.测试3

@Autowired注解属性required

required=false这个玩意的意思就是说找到就装配,找不到就拉到,就别装配了

require= true,未找到相应的bean对象,Spring就会抛出了异常

package com.tianxia.springannotation.service.impl;

import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * BookServiceImpl
 * @author liqb
 * @date 2023-04-21 16:38
 **/
@Service
public class BookServiceImpl implements BookService {

    @Autowired(required = false)
    private BookDao bookDao2;

    /**
     * 打印方法
     * @author liqb
     * @date 2023-05-06 13:09
     */
    public void print() {
        System.out.println(bookDao2);
    }

    @Override
    public String toString() {
        return "BookService [bookDao=" + bookDao2 + "]";
    }
}

3.2.测试@Qualifier注解

显示指定@Autowired注解装配哪个组件

package com.tianxia.springannotation.service.impl;

import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * BookServiceImpl
 * @author liqb
 * @date 2023-04-21 16:38
 **/
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    @Qualifier("bookDao")
    private BookDao bookDao2;

    /**
     * 打印方法
     * @author liqb
     * @date 2023-05-06 13:09
     */
    public void print() {
        System.out.println(bookDao2);
    }

    @Override
    public String toString() {
        return "BookService [bookDao=" + bookDao2 + "]";
    }
}

运行测试方法,输出结果如下所示:

在这里插入图片描述

此时尽管字段的名称为bookDao2,但是使用了@Qualifier注解显示指定了@Autowired注解装配bookDao对象,所以,最终的结果中输出了bookDao对象的信息。

3.3.测试@Primary注解

在Spring中,对同一个接口而言,可能会有几种不同的实现类,而默认只会采取其中一种实现的情况下,就可以使用@Primary注解来标注优先使用哪一个实现类。

在MainConfigOfAutowired配置类的bookDao()方法上添加上@Primary注解,如下所示:

package com.tianxia.springannotation.config;

import com.tianxia.springannotation.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

/**
 * 配置类
 * @author liqb
 * @date 2023-05-06 13:11
 **/
@Configuration
@ComponentScan({"com.tianxia.springannotation.service", "com.tianxia.springannotation.dao", "com.tianxia.springannotation.controller"})
public class MainConfigOfAutowired {

    /**
     * 注入bookDao对象
     * @author liqb
     * @date 2023-05-06 13:27
     * @return
     */
    @Primary
    @Bean("bookDao2")
    public BookDao bookDao() {
        BookDao bookDao = new BookDao();
        bookDao.setLable("2");
        return bookDao;
    }
}

注释掉BookService类中bookDao字段上的@Qualifier注解

package com.tianxia.springannotation.service.impl;

import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

/**
 * BookServiceImpl
 * @author liqb
 * @date 2023-04-21 16:38
 **/
@Service
public class BookServiceImpl implements BookService {

    // @Qualifier("bookDao")
    @Autowired(required = false)
    private BookDao bookDao2;

    /**
     * 打印方法
     * @author liqb
     * @date 2023-05-06 13:09
     */
    public void print() {
        System.out.println(bookDao2);
    }

    @Override
    public String toString() {
        return "BookService [bookDao=" + bookDao2 + "]";
    }
}

运行测试方法,输出结果如下所示:
在这里插入图片描述

此时lable的值为2,这说明装配了MainConfigOfAutowired配置类中注入的bookDao2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/18403.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构学习记录——哈夫曼树(什么是哈夫曼树、哈夫曼树的定义、哈夫曼树的构造、哈夫曼树的特点、哈夫曼编码)

目录 什么是哈夫曼树 哈夫曼树的定义 哈夫曼树的构造 图解操作 代码实现 代码解析 哈夫曼树的特点 哈夫曼编码 不等长编码 二叉树用于编码 哈夫曼编码实例 什么是哈夫曼树 我们先举个例子&#xff1a; 要将百分制的考试成绩转化成五分制的成绩 if(score < …

固态继电器的优点

固态继电器的优点包括紧凑性、抗冲击性和长寿命。以下是这些 SSR 优势中最重要的优势&#xff0c;让您了解为什么这项技术最适合您的应用&#xff1a; 开关速度快 固态继电器器件的主要优点之一是其开关速度。由于无需移动机械部件&#xff0c;SSR 可以在几微秒内切换。这是对…

【Java笔试强训 35】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 一、选择题 二、编程题 &#x1f525;年会抽奖…

小红书达人等级有哪些,达人种草力度判断

小红书对于产品及品牌的传播作用&#xff0c;来自于达人自身的分享。以笔记为媒介&#xff0c;对产品进行情景化展示&#xff0c;从而吸引消费&#xff0c;就被称作是种草。而种草力度的强弱&#xff0c;则与达人等级息息相关。下面&#xff0c;就来跟详细为大家解读。 一、小红…

设计模式——适配器模式(类适配器、对象适配器)

是什么&#xff1f; 我们平时的有线耳机接口分为USB的和Type-C的接口&#xff0c;但是手机的耳机插口却只有一个&#xff0c;像华为的耳机插口现在基本都是Type-c的&#xff0c;那如果我们现在只有USB接口的耳机怎么办呢&#xff0c;这个时候就需要使用到一个转换器&#xff0c…

公路交通气象站——提供及时的交通气象信息服务

我国幅员辽阔&#xff0c;跨经纬度广&#xff0c;气候多样。从气候类型划分&#xff1a;可以分为季风气候、温带大陆性气候和高寒气候。 气象的变化也在直接影响着我国各个地区的道路建设及通行&#xff0c;由于部分路段地势险峻伴随恶劣的气象变化&#xff0c;会直接影响驾驶人…

Java 10 字符串

1.API 1.1API 概述 什么是API ​ API (Application Programming Interface) &#xff1a;应用程序编程接口 java 中的 API ​ 指的就是 JDK 中提供的各种功能的 Java 类&#xff0c;这些类将底层的实现封装了起来&#xff0c;我们不需要关心这些类是如何实现的&#xff0c;只…

LeetCoed 2, 23, 25, 112, 113

文章目录 1. 两数相加2. K 个一组翻转链表3. 合并 K 个升序链表4. 路径总和I5. 路径总和II 1. 两数相加 题目详情见: LeetCode2. 两数相加 题目描述相对来说比较绕, 我们可以直接理解为两个多位的整数相加, 只不过整数的每一位都是通过链表进行存储; 比如, 整数 342, 通过链表…

三分钟教你Mac下安装VmWare虚拟机

大数据课程课前环境准备&#xff1a;mac中安装三台linux服务器 一、课前准备 准备一台内存最少8G&#xff08;建议16G&#xff09;、cpu i7 4核的电脑 二、课堂主题 安装虚拟化软件VMware准备3台linux虚拟机 三、课堂目标 完成mac下3个虚拟机的安装 四、知识要点 文档说…

浅析智慧充电桩云平台的技术设计方案

自从我国提出“新基建”以来&#xff0c;充电基础设施产业也成为行业的话题与关注焦点。据数据统计&#xff0c;2021年&#xff0c;中国新能源汽车保有量达到784万辆&#xff0c;预计2025年&#xff0c;中国新能源汽车保有量达到2672万辆&#xff0c;2025年充电桩数量将达到654…

【沐风老师】一步一步教你在3dMax中进行UVW贴图和展开UVW的方法

将简单或程序材质应用于对象并不难。但是当表面需要在其上显示某种纹理时&#xff0c;它会变得更加复杂。任何纹理贴图都放在材质的 Diffuse 插槽中&#xff0c;但渲染的结果可能无法预测。这就是为什么我们需要了解 3DMAX 如何将纹理应用于 3D 对象&#xff0c;什么是 UVW 贴图…

weblogic ssrf 漏洞复现

一.前言 Weblogic中存在一个SSRF漏洞&#xff0c;利用该漏洞可以发送任意HTTP请求&#xff0c;进而攻击内网中redis、fastcgi等脆弱组件。 二.环境搭建 在docker中开启环境 sudo docker-compose up -d sudo docker-compose ps #查看状态访问http://your-ip:7001/uddiexpl…

【数码】收音机,德生PL380使用教程与注意事项

文章目录 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09;2、电池和电池模式的匹配3、收音机天线与信号&#xff0c;耳机与噪音F、参考资料 1、主界面功能介绍&#xff08;注意闹钟和自动关机&#xff09; 红色的按钮&#xff1a;power 按一下开机&#xff0c;按…

25个著名的WordPress网站案例

想创建免费网站吗&#xff1f;从易服客建站平台开始 500M免费空间&#xff0c;可升级为20GB电子商务网站 创建免费网站 WordPress 内容管理系统为全球35%的网站提供支持。鉴于目前有 17 亿个站点&#xff0c;并且还在增加&#xff0c;您可以算出每秒向网站访问者提供内容的W…

牛客网剑指offer|中等题day2|JZ22链表中倒数最后k个结点(简单)、JZ35复杂链表的复制(复杂)、JZ77按之字形顺序打印二叉树(中等)

JZ22链表中倒数最后k个结点(简单) 链接&#xff1a;链表中倒数最后k个结点_牛客题霸_牛客网 /*** struct ListNode {* int val;* struct ListNode *next;* ListNode(int x) : val(x), next(nullptr) {}* };*/ class Solution { public:/*** 代码中的类名、方法名、参数名已经指…

一、PEMFC基础之热力学

一、PEMFC基础之热力学 1.内能U、焓H、熵S、吉布斯自由能G、赫姆霍兹自由能F关系图2.可逆电压与温度和压力的关系3.能斯特方程4.燃料电池效率 1.内能U、焓H、熵S、吉布斯自由能G、赫姆霍兹自由能F关系图 2.可逆电压与温度和压力的关系 标准状态可逆电压Er计算&#xff1a; E …

基于springboot的4S店车辆管理系统(源码等)

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时代&…

Linux进程状态及优先级

本文已收录至《Linux知识与编程》专栏&#xff01; 作者&#xff1a;ARMCSKGT 演示环境&#xff1a;CentOS 7 进程状态及优先级 前言正文进程状态就绪运行状态R阻塞睡眠状态 S休眠状态D挂起 暂停状态T前台与后台进程待追踪暂停状态t 死亡状态 X僵尸状态 Z 孤儿进程进程优先级查…

美颜SDK的隐私保护与安全性分析

随着智能手机和移动应用的普及&#xff0c;美颜SDK已经成为了很多应用的标配。美颜SDK的使用可以让用户在拍照或者视频聊天时&#xff0c;实现自拍美颜、滤镜、磨皮、瘦脸等效果。但是&#xff0c;在享受美颜SDK带来的便利的同时&#xff0c;我们也需要关注美颜SDK的隐私保护与…

配置文件Application.properties

配置文件Application.properties 属性配置配置文件的多种格式yaml的数据格式读取yaml文件中的属性值读取yaml文件中的全部属性yaml文件 数据库的属性 属性配置 在application.properties中添加server.port端口号即可 # 服务器端口配置 server.port80# 修改banner 关闭banner …