当前位置: 首页 > news >正文

基于注解的自动装配~

@Autowired:实现自动装配功能的注解

@Autowired注解能够标识的位置:

 标识在成员变量上,此时不需要设置成员变量的set方法标识在成员变量对应的set方法上标识在为当前成员变量赋值的有参构造上

使用注解进行自动装配,只要在其成员变量上添加@Autowired即可在之前基于XML的自动装配时,我们使用的是autowire属性,我们需要为其成员变量设置set和get方法,但使用注解的方式进行自动装配是不需要要这一过程的

控制层:调用service处理业务逻辑

package springIocAnnotation_packages.spring_controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import springIocAnnotation_packages.spring_Service.UserService;@Controller("controller")
public class UserController {@Autowired //使用@Autowired表示为自动装配private UserService userService;public void saveUser(){userService.saveUser();}
}

业务层:

package springIocAnnotation_packages.spring_Service;import org.springframework.stereotype.Service;@Service
public interface UserService {void saveUser();
}

业务层的实现类:业务层中调用Dao实现持久化操作

package springIocAnnotation_packages.spring_Service.impl;import org.springframework.stereotype.Service;
import springIocAnnotation_packages.spring_Dao.UserDao;
import springIocAnnotation_packages.spring_Service.UserService;@Service
public class UserServiceImpl implements UserService {@Autowiredprivate  UserDao userDao;@Overridepublic void saveUser() {userDao.saveUser();}
}

持久层:

package springIocAnnotation_packages.spring_Dao;public interface UserDao {void saveUser();
}

持久层实现类:

package springIocAnnotation_packages.spring_Dao.impl;import org.springframework.stereotype.Repository;
import springIocAnnotation_packages.spring_Dao.UserDao;@Repository
public class UserDaoImpl implements UserDao {@Overridepublic void saveUser() {System.out.println("保存成功~");}
}

spring-ioc-annotation.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="springIocAnnotation_packages"></context:component-scan>
</beans>

测试类如下:

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import springIocAnnotation_packages.spring_controller.UserController;public class spring_ByAnnotationTest {@Testpublic void test(){ApplicationContext ioc=new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");UserController userController= ioc.getBean( UserController.class);userController.saveUser();}
}

测试结果如下所示:

在这里插入图片描述

@Autowired:实现自动装配的原理

在之前的学习中,我们了解到,自动装配是将autowire属性的值设置为byName[将要赋值的属性的名字作为bean的id,再在IOC容器中去匹配到某一个bean为当前属性进行赋值]或者byType[根据类型在IOC容器中获取类型匹配的bean为当前的属性自动进行赋值]

那么现在我们使用注解的方式到底是根据byName还是byType呢?

答案:byType

那么为什么不能是byName呢?

我们这里要赋值的成员变量叫userservice,和它类型匹配的是UserServiceImpl,很明显当前的属性名和其id是不相同的,因为我们在上篇文章中就说过,使用注解
+扫描的方式管理的bean的id默认是其类的小驼峰形式,而UserServiceImpl的小驼峰形式为userServiceImpl,对于持久层也是如此,userDao和它类型匹配的是UserDaoImpl,它的小驼峰形式为userDaoImpl,由此可说明@Autowired默认通过byType的方式,在IOC容器中通过类型匹配到某个bean来为
尚属性进行赋值

既然是根据类型,那么就会发生匹配到多个类或者是一个都没匹配到,如下所示:

在XML文件中,添加两个bean对象,使其id和我们的成员变量一致

<bean id="userService" class="springIocAnnotation_packages.spring_Service.impl.UserServiceImpl"></bean>
<bean id="userDao" class="springIocAnnotation_packages.spring_Dao.impl.UserDaoImpl"></bean>

经过上述修改以及结合我们之前学过知识,我们知道这种情况下,会抛出无法匹配到唯一bean的异常,那么事实真的如此吗?

一测便知:

测试结果如下所示:

在这里插入图片描述

竟然输出了保存成功,难道是我们之前学习的知识有问题?

那当然不是,原因是 :默认情况下,它是通过byType实现自动装配,但是如果有多个类型匹配的bean,它将通过byName

既然byType不行,那就byName,但是有没有一种情况是二者都不满足呢?

也就是:如果byType和byName的方式都无法实现自动装配,即IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的的属性的属性名不一致,那么会抛出异常:NoUniqueBeanDefinitionException

测试如下:

手动修改id的值,使其与成员变量名不相同,下述这种情况就满足byType和byName都无法实现自动装配

<context:component-scan base-package="springIocAnnotation_packages"></context:component-scan>
<bean id="Service" class="springIocAnnotation_packages.spring_Service.impl.UserServiceImpl"></bean>
<bean id="Dao" class="springIocAnnotation_packages.spring_Dao.impl.UserDaoImpl"></bean>

测试结果如下:

在这里插入图片描述

针对上述这种情况,我们的解决办法为在其成员变量上添加@Qualifier注解,通过该注解的value值去指定某个bean的id,将这个bean为该属性赋值

如下所示:

在这里插入图片描述

在这里插入图片描述

测试结果如下所示:

在这里插入图片描述

那么如果byType一个都没匹配到呢?

若IOC容器中没有任何一个类型匹配的bean,此时抛出异常NoSuchBeanDefinitionException,在@Autowired注解中有个属性required,默认值为true,要求必须完成自动装配,可以将required设置为false,设置为false之后的效果即为能装配则装配,不能装配则使用属性的默认值

测试如下:

1:我们将XML文件中的bean对象删除
2:将所有的@Qualifier删除
3:删除UserServiceImpl类上@Service注解

三步完成之后,进行测试:

报错如下:

//没有任何一个UserService的类可用,至少需要一个bean来完成自动装配的效果,所依赖的Autowired注解中的required属性//导致异常产生的原因就是当前Autowired注解中的required属性的值为true,默认情况下必须完成自动装配,不完成自动装配直接报错
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'springIocAnnotation_packages.spring_Service.UserService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

上述所说的也是一种特殊情况,既然是Autowired注解中的required属性的值为true导致的异常产生,那么我们将其设置为 false是否可以解决这个问题呢?

测试结果如下:

在这里插入图片描述

上面我们说默认的byType不行,那么我们就使用byName,要是还不行,再使用新的注解@Qualifier,但这种特殊的情况在实际的开发中是非常少的,因为一个类型的bean,我们只会在IOC容器中配置一次,我们不可能配置多次,这个时候我们使用默认的byType即可

相关文章:

基于注解的自动装配~

Autowired&#xff1a;实现自动装配功能的注解 Autowired注解能够标识的位置&#xff1a; 标识在成员变量上&#xff0c;此时不需要设置成员变量的set方法标识在成员变量对应的set方法上标识在为当前成员变量赋值的有参构造上使用注解进行自动装配&#xff0c;只要在其成员变量…...

【深度学习】【分布式训练】Collective通信操作及Pytorch示例

相关博客 【深度学习】【分布式训练】Collective通信操作及Pytorch示例 【自然语言处理】【大模型】大语言模型BLOOM推理工具测试 【自然语言处理】【大模型】GLM-130B&#xff1a;一个开源双语预训练语言模型 【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介…...

Spring常用注解说明

目录 1.常用注解 2.特别说明 3.xml及注解方式 1.常用注解 (1) SpringBootApplication (2) ControllerRestControllerRequestMappingRequestParamPathVariableGetMappingPostMappingPutMappingDeleteMappingResponseBodyRequestBodyCrossOrigin (3) ConfigurationBeanServ…...

13-C++面向对象(纯虚函数(抽象类)、多继承、多继承-虚函数、菱形继承、虚继承、静态成员)

虚析构函数 存在父类指针指向子类对象的情况&#xff0c;应该将析构函数声明为虚函数&#xff08;虚析构函数&#xff09; 纯虚函数 纯虚函数&#xff1a;没有函数体且初始化为0的虚函数&#xff0c;用来定义接口规范 抽象类&#xff1a; 含有纯虚函数的类&#xff0c;不可以实…...

Android DataBinding 自定义View实现数据双向绑定

看不懂的可以先看看单向数据绑定&#xff1a;Android DataBinding数据变化时自动更新界面_皮皮高的博客-CSDN博客 然后再确定已经启动了dataBinding的情况下&#xff0c;按下面的顺序来&#xff1a; 首先创建一个自定义View&#xff1a; import android.content.Context imp…...

网络安全中的渗透测试主要那几个方面

渗透测试中主要有软件测试和渗透测试。 1、测试对象不同 软件测试&#xff1a;主要测试的是程序、数据、文档。 渗透测试&#xff1a;对象主要为网络设备、主机操作系统、数据库系统和应用系统。 2、测试内容不同 软件测试&#xff1a;主要工作内容是验证和确认&#xff0c;发…...

Cursor:GPT-4 驱动的强大代码编辑器

Cursor &#xff08;https://www.cursor.so/&#xff09;是 GPT-4 驱动的一款强大代码编辑器&#xff0c;可以辅助程序员进行日常的编码。下面通过一个实际的例子来展示 Cursor 如何帮助你编程。这个例子做的事情是网页抓取。抓取的目标是百度首页上的百度热搜&#xff0c;如下…...

C/C++中for语句循环用法及练习

目录 语法 下面是 for 循环的控制流&#xff1a; 实例 基于范围的for循环(C11) 随堂笔记&#xff01; C语言训练-计算1~N之间所有奇数之和 题目描述 输入格式 输出格式 样例输入 样例输出 环形方阵 干货直达 for 循环允许您编写一个执行特定次数的循环的重复控制结构。…...

AnimatorOverrideController说明

unity-AnimatorOverrideControllerhttps://docs.unity.cn/cn/current/ScriptReference/AnimatorOverrideController.html 用于控制动画器重写控制器的接口。 动画器重写控制器的用途是重写某个控制器的动画剪辑&#xff0c;从而为给定化身定制动画。 在运行时基于相同的 Anim…...

1.4、第三阶段 MySQL数据库

root数据库技术 一、数据库理论 1 什么是数据库技术 数据库技术主要研究如何组织、存储数据&#xff0c;并如何高效地提取和处理数据。 2 什么是SQL SQL&#xff08;Structured Query Language&#xff09;结构化查询语言 SQL是操作数据库的命令集&#xff0c;也是功能齐全的…...

LeetCode:202. 快乐数

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; &#x1f33b;算法&#xff0c;不如说它是一种思考方式&#x1f340;算法专栏&#xff1a; &#x1f449;&#x1f3fb;123 一、&#x1f331;202. 快乐数 题目描述&#xff1a;编写一个算法来判断一个数 n 是不是快…...

Android 14 新功能之 HighLights:快速实现文本高亮~

日常开发中可能会遇到给 TextView 的全部或部分文本增加高亮效果的需求&#xff0c;以前可能是通过 Spannable 或者 Html 标签实现。 升级 Android 14 后就不用这么迂回了&#xff0c;因其首次引入直接设置高亮的 API&#xff1a;HighLights。需要留意的是 HighLights API 和 …...

[渗透教程]-004-嗅探工具-Nmap

文章目录 Nmap介绍基本操作进阶操作Nmap介绍 nmap是一个网络扫描和主机检测工具,它可以帮助用户识别网络上的设备和服务。获取主机正在运行哪些服务,nmap支持多种扫描,UDP,TCP connect(),TCP SYN(半开扫描) ftp代理,反向标志,ICMP,FIN,ACK扫描,ftp代理,反向标志,ICMP. 可以用于…...

大数据技术之Hive SQL题库-初级

第一章环境准备1.1 建表语句hive>-- 创建学生表 DROP TABLE IF EXISTS student; create table if not exists student_info(stu_id string COMMENT 学生id,stu_name string COMMENT 学生姓名,birthday string COMMENT 出生日期,sex string COMMENT 性别 ) row format delim…...

常见HTTP状态码汇总

文章目录1xx: 信息2xx: 成功3xx: 重定向4xx: 客户端错误5xx: 服务器错误1xx: 信息 状态码描述100 Continue服务器仅接收到部分请求&#xff0c;但是一旦服务器并没有拒绝该请求&#xff0c;客户端应该继续发送其余的请求。101 Switching Protocols服务器转换协议&#xff1a;服…...

蓝桥杯刷题冲刺 | 倒计时15天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.年号字串2.裁纸刀3.猜生日1.年号字串 题目 链接&#xff1a; 年号字串 - 蓝桥云课 (lanqiao.c…...

【差分数组】

差分数组一维差分差分数组的作用差分矩阵结语一维差分 输入一个长度为 n 的整数序列。接下来输入 m个操作&#xff0c;每个操作包含三个整数 l,r,c&#xff0c;表示将序列中 [l,r] 之间的每个数加上 c &#xff0c;请你输出进行完所有操作后的序列。 输入格式 第一行包含两个…...

2022年NOC软件创意编程(学而思)决赛小学高年级组scratch

2022NOC决赛图形化小高组 一、选择题 1.运行下面的程序,最终“我的变量”的值是多少? 2.希望定义一个函数如下,可以让角色旋转指定的圈数。里面空缺的地方填上什么数字比较合适? 3.运行程序,在舞台上可以看见几个角色 ? 4.运行程序,角色会依次说什么 ? 5.我们都知…...

[JAVA]一步接一步的一起开发-图书管理系统(非常仔细,你一定能看懂)[1W字+]

目录 1.想法 2.框架的搭构 2.1图书 2.1.1Book类 2.1.2BookList类 2.2用户 2.2.1User抽象类 2.2.2AdminUser类&#xff08;管理者&#xff09; 2.2.3NormalUser 2.3操作 操作接口 借阅操作 删除操作 查询操作 归还图书 展示图书 退出系统 2.4小结 3.主函数的编…...

大数据周会-本周学习内容总结07

目录 01【hadoop】 1.1【编写集群分发脚本xsync】 1.2【集群部署规划】 1.3【Hadoop集群启停脚本】 02【HDFS】 2.1【HDFS的API操作】 03【MapReduce】 3.1【P077- WordCount案例】 3.2【P097-自定义分区案例】 历史总结 01【hadoop】 1.1【编写集群分发脚本xsync】…...

GBase 8c存储过程调试接口使用指南

本文针对南大通用 GBase 8c 数据库&#xff0c;围绕存储过程的使用与问题定位&#xff0c;基于 DBE_PLDEBUGGER 调试接口&#xff0c;详细说明存储过程调试的核心接口、标准流程、常用命令与完整实战操作步骤&#xff0c;帮助用户快速掌握调试方法&#xff0c;高效定位与解决存…...

为什么92.7%的用户生成不出真正包豪斯风格?——3大认知陷阱与48小时速成调参路径

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;包豪斯设计哲学的数字转译本质 包豪斯所倡导的“形式追随功能”“少即是多”“艺术与技术的新统一”&#xff0c;在当代前端工程、UI系统设计与可访问性实践中&#xff0c;已不再仅是美学信条&#xff0c;而成…...

dy app抓包分析

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;抓包展示总结1.出于安全考虑,本章未提供…...

配置Hermes Agent使用自定义Taotoken作为模型供应商的步骤

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 配置Hermes Agent使用自定义Taotoken作为模型供应商的步骤 1. 准备工作&#xff1a;获取必要的凭证 在开始配置之前&#xff0c;你…...

Azure 资源管理器编程:resourcemanager 模块的 100+ 服务集成

Azure 资源管理器编程&#xff1a;resourcemanager 模块的 100 服务集成 【免费下载链接】azure-sdk-for-go This repository is for active development of the Azure SDK for Go. For consumers of the SDK we recommend visiting our public developer docs at: 项目地址:…...

从线条到有宽度的箭头:CAD多段线宽度(W)设置实战,轻松搞定示意图与流程图

从线条到有宽度的箭头&#xff1a;CAD多段线宽度&#xff08;W&#xff09;设置实战&#xff0c;轻松搞定示意图与流程图 在技术文档、工艺流程图或平面布置图的绘制中&#xff0c;单调的细线往往难以清晰表达设计意图。当我们需要突出管道流向、标注关键区域或绘制专业箭头时&…...

433MHz无线模块解码避坑指南:从示波器抓波形到STM32代码实现的完整流程

433MHz无线模块解码实战&#xff1a;从波形分析到STM32代码优化的全流程解析 1. 解码前的硬件准备与信号捕获 当你第一次拿到433MHz无线模块时&#xff0c;最令人困惑的往往是"为什么我的代码无法正确解码&#xff1f;"要解决这个问题&#xff0c;我们需要从最基础的…...

PHP Intelephense与Composer依赖管理:提升PHP开发效率的终极指南

PHP Intelephense与Composer依赖管理&#xff1a;提升PHP开发效率的终极指南 【免费下载链接】vscode-intelephense PHP intellisense for Visual Studio Code 项目地址: https://gitcode.com/gh_mirrors/vs/vscode-intelephense 在PHP开发中&#xff0c;PHP Intelephen…...

TeamPass后台任务管理:自动化维护和清理操作手册

TeamPass后台任务管理&#xff1a;自动化维护和清理操作手册 【免费下载链接】TeamPass Collaborative Passwords Manager 项目地址: https://gitcode.com/gh_mirrors/te/TeamPass TeamPass作为一款协作密码管理器&#xff0c;其后台任务管理功能是确保系统高效稳定运行…...

parse库错误处理与异常管理:构建可靠的字符串解析应用

parse库错误处理与异常管理&#xff1a;构建可靠的字符串解析应用 【免费下载链接】parse Parse strings using a specification based on the Python format() syntax. 项目地址: https://gitcode.com/gh_mirrors/pa/parse 在Python开发中&#xff0c;字符串解析是一项…...