【Spring】——16、使用@Autowired、@Qualifier、@Primary这三大注解自动装配组件?

news2024/11/23 9:16:24

在这里插入图片描述

📫作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等

本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~

文章目录

  • 1、@Autowired(类型自动装配)
    • 1.1、源码
    • 1.2、使用
      • 1.2.1、属性上方
      • 1.2.2、setter方法上方
      • 1.2.3、构造方法上方
    • 1.3、总结
  • 2、@Qualifier(名称自动装配)
    • 2.1、源码
    • 2.2、使用
  • 3、@Primary
    • 3.1、源码
    • 3.2、使用场景(多数据源)
      • 3.2.1、application.properties配置
      • 3.2.2、config配置
        • 3.2.2.1、FirstDataSourceConfig
        • 3.2.2.2、SecondDataSourceConfig
        • 3.2.2.3、将mapper和xml文件分包放置
  • 4、参考

  • 前提回顾:其实这篇文章我不太想写,因为正常工作中,基本上天天都在用,写了也没啥意思,但是为了保证整个目录的以后成一个体系,我还是花时间去写了。

1、@Autowired(类型自动装配)

  • 作用:从容器中查找符合属性类型的对象自动注入属性中。用于代替中的依赖注入配置。
  • 作用域:属性上方、setter方法上方、构造方法上方,参数,注解

1.1、源码

首先我们先看一下@Autowired的底层实现
在这里插入图片描述

  • 说明
    • 1、@Autowired注解默认是优先按照类型(类.class)去容器中找对应的组件,若找到则就赋值。相当于是调用了如下这个方法:
applicationContext.getBean(类名.class);
  • 容器 中有多个对象匹配类型时,会找beanId等于属性名的对象,找不到会报错。这时就相当于是调用了如下这个方法:
applicationContext.getBean("组件的id");

1.2、使用

1.2.1、属性上方

  • @Autowired写在属性上方进行依赖注入时,可以省略setter方法

例子如下:

@Component
    public class StudentService { 
        @Autowired
        private StudentDao studentDao;

        public Student findStudentById(int id) {
            return studentDao.findById(id); 
        }
    }

@Test
    public void t2(){
        ApplicationContext ac = new 
            ClassPathXmlApplicationContext("bean.xml") 
            ;
        StudentService studentService = (StudentService)ac.getBean("studentService");
        System.out.println(studentService.findStudentById(1));
}

1.2.2、setter方法上方

@Component
    public class StudentService { 

        private StudentDao studentDao;

        @Autowired
        public void setStudentDao(StudentDao studentDao) {
            this.studentDao = studentDao;
        }

        public Student findStudentById(int id) {
            return studentDao.findById(id); 
        }
    }

@Test
    public void t2(){
    ApplicationContext ac = new 
        ClassPathXmlApplicationContext("bean.xml") 
        ;
    StudentService studentService = (StudentService)ac.getBean("studentService");
    System.out.println(studentService.findStudentById(1));
}
  • 当@Autowired注解标注在方法上时,Spring容器在创建当前对象的时候,就会调用相应的方法为对象赋值。如果标注的方法存在参数时,那么方法使用的参数和自定义类型的值,需要从IOC容器中获取。

1.2.3、构造方法上方

@Component
    public class StudentService { 

        private StudentDao studentDao;

        @Autowired
        public StudentService(StudentDao studentDao) {
            this.studentDao = studentDao;
        }

        public Student findStudentById(int id) {
            return studentDao.findById(id); 
        }
    }

@Test
    public void t2(){
    ApplicationContext ac = new 
        ClassPathXmlApplicationContext("bean.xml") 
        ;
    StudentService studentService = (StudentService)ac.getBean("studentService");
    System.out.println(studentService.findStudentById(1));
}
  • 使用@Autowired注解标注在构造方法上时,构造方法中的参数对象也是从IOC容器中获取的。
  • 使用@Autowired注解标注在构造方法上时,如果组件中只有一个有参构造方法,那么这个有参构造方法上的@Autowired注解可以省略,并且参数位置的组件还是可以自动从IOC容器中获取。

1.3、总结

  • 如果方法只有一个IOC容器中的对象作为参数,当@Autowired注解标注在这个方法的参数上时,我们可以将@Autowired注解省略掉。也就说@Bean注解标注的方法在创建对象的时候,方法参数的值是从IOC容器中获取的,此外,标注在这个方法的参数上的@Autowired注解可以省略。
  • 其实,我们用到最多的还是把@Autowired注解标注在方法位置,即使用@Bean注解+方法参数这种形式,此时,该方法参数的值从IOC容器中获取,并且还可以默认不写@Autowired注解,因为效果都是一样的,都能实现自动装配!

2、@Qualifier(名称自动装配)

  • 作用:在按照类型注入对象的基础上,再按照bean的id(名称)注入
  • 作用域:@Qualifier必须和@Autowired一起使用。

2.1、源码

首先我们看一下@Qualifier的源码
在这里插入图片描述

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

2.2、使用

@Component
    public class StudentService { 
        @Autowired
        @Qualifier("studentDaoImpl2") 
        private StudentDao studentDao;
        public Student findStudentById(int id){ 
            return studentDao.findById(id);
        } 
    }

3、@Primary

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

3.1、源码

在这里插入图片描述

3.2、使用场景(多数据源)

3.2.1、application.properties配置

spring.datasource.first.url = jdbc:mysql://192.168.0.1:3306/test1?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&useSSL=false
spring.datasource.first.username = root
spring.datasource.first.password = 123456
spring.datasource.first.driverClassName = com.mysql.jdbc.Driver

spring.datasource.second.url = jdbc:mysql://192.168.0.2:3306/test1?autoReconnect=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT&useSSL=false
spring.datasource.second.username = root
spring.datasource.second.password = 123456
spring.datasource.second.driverClassName = com.mysql.jdbc.Driver

#获取连接时验证
spring.datasource.first.test-on-borrow=true
#验证连接的有效性
spring.datasource.first.test-while-idle=true
#空闲连接回收的时间间隔,和test-while-idle一起使用
spring.datasource.first.time-between-eviction-runs-millis=300000
#连接池空闲连接的有效时间
spring.datasource.first.min-evictable-idle-time-millis=1800000
spring.datasource.first.test-on-return=true
spring.datasource.first.validation-query=SELECT 1

#获取连接时验证
spring.datasource.second.test-on-borrow=true
#验证连接的有效性
spring.datasource.second.test-while-idle=true
#空闲连接回收的时间间隔,和test-while-idle一起使用
spring.datasource.second.time-between-eviction-runs-millis=300000
#连接池空闲连接的有效时间
spring.datasource.second.min-evictable-idle-time-millis=1800000
spring.datasource.second.test-on-return=true
spring.datasource.second.validation-query=SELECT 1

3.2.2、config配置

每个数据源都需要一个配置类。同时dao包和mapping包下需要分别再分成first包和second包存放对应的Mapper文件和xml文件。

3.2.2.1、FirstDataSourceConfig

@Configuration
@MapperScan(basePackages = "com.test.dao.first", sqlSessionFactoryRef = "firstSqlSessionFactory")
public class FirstDataSourceConfig{
    
    @Primary
    @Bean(name = "firstDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.first")
    public DataSource firstDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "firstSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("firstDataSource") Datasource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapping/first/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "firstSqlSessionTemplate")
    public SqlSessionTemplate firstSqlSessionTemplate(@Qualifier("firstSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

3.2.2.2、SecondDataSourceConfig

@Configuration
@MapperScan(basePackages = "com.test.dao.second", sqlSessionFactoryRef = "secondSqlSessionFactory")
public class SecondDataSourceConfig{
    @Primary
    @Bean(name = "secondDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.second")
    public DataSource secondDataSource(){
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "secondSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("secondDataSource") Datasource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapping/second/*.xml"));
        return bean.getObject();
    }
    
    @Bean(name = "secondSqlSessionTemplate")
    public SqlSessionTemplate 
    secondSqlSessionTemplate(@Qualifier("secondSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

3.2.2.3、将mapper和xml文件分包放置

将first和second数据源相关的maper和xml文件分别放在dao包和mapping包下的first和second目录中。这个时候就已经可以连接数据库测试了,可以从不同数据源的mapper中操作数据。

4、参考

  • https://blog.csdn.net/sfh2018/article/details/107491822

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Redis】Redis事务工作原理解析与分布式事务实战(Redis专栏启动)

📫作者简介:小明java问道之路,专注于研究 Java/ Liunx内核/ C及汇编/计算机底层原理/源码,就职于大型金融公司后端高级工程师,擅长交易领域的高安全/可用/并发/性能的架构设计与演进、系统优化与稳定性建设。 &#x1…

8.Django大型电商项目之商品添加分页

1.添加分页 添加分页在Django中使用自带分页器paginator 1.1 配置setting settings中配置分页数量 # 每页显示记录条数 PER_PAGE_NUMBER 81.2 配置views 完成分页栏使用paginator创建对象,返回选中条数 from django.shortcuts import render from goodsapp.mo…

桶排序算法

题目 代码1&#xff1a; #include <stdio.h> int main() {int sz0;scanf("%d",&sz);int arr[sz];//输入int i0;for (i0;i<sz;i){scanf("%d",&arr[i]);}//删除多余相同元素int j0;int k0;for (i0;i<sz;i){if (i0){arr[j]arr[i];}else{…

MyBatis批量保存(Oracle)MyBatis批量插入时,组装SQL过长会有问题,一定要根据批量插入数据量进行切割,再批次提交保存!!!

MyBatis批量保存&#xff08;Oracle&#xff09; oracle 批量插入与mysql 的批量插入的方式不同 insert into tablename()values(),(),(); ---这个是mysql 的批量插入形式 insert all into tablename() values() into tablename() values() -------这个是Oracle批量插入形式 你…

大数据测试 - 数仓测试

前言 对于数据仓库的测试来说底层的系统会有很多有自建的集群使用 spark 或者 flink 测试&#xff0c;也有很多直接使用云厂商的产品比如 datworks 等等&#xff0c;再这里我想分享下抛开环境&#xff0c;只对数据仓库测试的一些小心得。 数仓分层设计 标准数仓分为 ODS,DWD…

java计算机毕业设计基于安卓Android的微整形美容app

项目介绍 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设…

前缀和问题

前缀和 一维二维 ac795. 前缀和【一维】 输入一个长度为 nn 的整数序列。 接下来再输入 mm 个询问&#xff0c;每个询问输入一对 l,rl,r。 对于每个询问&#xff0c;输出原序列中从第 ll 个数到第 rr 个数的和。 输入格式 第一行包含两个整数 nn 和 mm。 第二行包含 nn…

基于android的资源文件管理器

软 件 学 院 毕业实训报告 课题名称&#xff1a; android资源管理器 专 业&#xff1a; 软件设计&#xff08;游戏开发方向&#xff09; 班 级&#xff1a; 学 号&#xff1a; 学生姓名&#xff1a; 指导教师&#xff1a; 年 月 日 摘 要 相信大家对Android的发展历史…

Nacos-配置中心,特性,启动,集成mysql,快速入门

Nacos - 配置管理 目录Nacos - 配置管理1. 什么是配置中心1.1 什么是配置1.2 什么是配置中心2 Nacos****简介2.1 主流配置中心对比2.2 Nacos****简介2.3 Nacos****特性3 Nacos 快速入3.1 安装 Nacos Server3.1.1 预备环境准备3.1.2 下载源码或者安装包3.1.3 启动服务器3.1.4 OP…

HTML班级网页设计 基于HTML+CSS+JS制作我们的班级网页(web前端学生网页设计作品)

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

计算机毕业设计---java+springboot宠物商城系统

一、项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot Maven mybatis Vue 等等组成&#xff0c;B/…

光栅尺差分计数/频率5MHz/磁栅尺编码器差分脉冲计数采集模块

产品特点&#xff1a; ● 光栅尺磁栅尺解码转换成标准Modbus RTU协议 ● 光栅尺5V差分信号直接输入&#xff0c;4倍频计数 ● 模块可以输出5V的电源给光栅尺供电 ● 高速光栅尺磁栅尺计数&#xff0c;频率可达5MHz ● 支持4个光栅尺同时计数&#xff0c;可识别正反转 ● …

Oracle函数

目录 一、数值函数 1.ABS(value)&#xff1a;绝对值 2.CEIL(value)&#xff1a;向上取整 3.FLOOR(value)&#xff1a;向下取整 4.ROUND(value)&#xff1a;四舍五入 5.MOD(value(被除数),divisor(除数))&#xff1a;求模 6.SIGN(value)&#xff1a;判断正(0)负(-1)和零(…

隐私计算学习笔记

目录 安全保护技术和应用总结 基础隐私计算技术在联邦学习中的应用 参考书籍 图片来源&#xff1a; https://www.basebit.ai/en/Statics/Images/en/dbys.png 隐私计算技术的产生是互联网、大数据以及区块链等技术发展到一定阶段的必然成果&#xff0c;以下为大家分享读书笔…

01-32-spring5-bean-ioc-aop

01-spring5&#xff1a; spring 1、spring概念 1、什么是spring及优点 Spring框架使Java EE应用程序的开发更加简捷&#xff0c;通过使用POJO为基础的编程模型促进良好的编程风格。 轻量级&#xff1a;Spring在大小和透明性方面绝对属于轻量级的&#xff0c;基础版本的Spr…

【推荐系统学习笔记】-- 2、特征工程

1、可利用的特征 1.1 用户行为特征 显性反馈行为&#xff1a;点赞、评分、评价等隐形反馈行为&#xff1a;点击、浏览、播放、加入购物车等 1.2 用户关系数据 显性&#xff1a;关注、好友关系隐形&#xff1a;点赞、共同观影使用Graph Embedding生成用户和物品的Embedding …

[附源码]Python计算机毕业设计SSM基于web的托育园管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

蓝牙遥控小车基础篇

开发环境&#xff1a; STM32F103R8T6最小系统板&#xff08;IO顺序引出&#xff09; 3D建模蓝牙遥控小车STL 蓝牙遥控小车纯HAL库代码 TP-Bluetooth-Car.apk蓝牙apk 原理&#xff1a;&#xff08;写代码前必须要知道模块的参数&#xff09; 蓝牙模块HC-05使用指南 HC-05蓝…

C++入门——函数重载

C入门——函数重载与缺省 先说说什么是缺省 大家生活中都知道什么关于缺省这个词的例子吗&#xff1f; 肯定是一头雾水&#xff0c;没事我举一个例子&#xff0c;给大家解释一下。 假如小菜是一个舔狗&#xff0c;他天天跟女神买早餐、嘘寒问暖。可是女神还是天天不为所动&am…