【进阶】Spring更简单的读取和存储对象

news2024/12/29 15:57:00

努力经营当下,直至未来明朗!

文章目录

  • 一、存储Bean对象
    • 一)前置工作:配置扫描路径(重要)
    • 二)添加注解存储Bean对象
      • 3. 五大类注解:
      • 4. 方法注解:
      • 6. 相关问题
      • 7. 补充【结论、查看源码】
    • 三)为什么要使用这么多类注解
    • 四)方法注解 @Bean
  • 二、获取Bean对象(对象装配)
    • 1. 属性注入
    • 2. 构造方法注入(官方推荐写法)
    • 3. Setter注入
    • 4. 三种注入方式的区别【经典面试题】
    • 5. @Resource:另⼀种注⼊关键字
    • 6. @Resource和@Autowired的区别【经典面试题】
    • 7. 同⼀类型多个 @Bean 报错
  • 小结


普通小孩也要热爱生活!

一、存储Bean对象

在spring-config.xml中配置bean标签比较麻烦,此时就可以使用注解。(注解在jdk1.5之后出现)

一)前置工作:配置扫描路径(重要)

  1. 配置xml文件

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:content="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">
       <content:component-scan base-package="com.demo.component"></content:component-scan>

       <bean id="article" class="com.demo.component.ArticleController"></bean>
</beans>

0

  1. 补充:包的平铺
    1

二)添加注解存储Bean对象

  1. 类注解:将注解写到类中,将某个依赖动态地加载到类中,将类对象存储到Spring中。
  2. 方法注解:将方法返回的对象存储到Spring中。

3. 五大类注解:

1)@Controller(控制器存储):默认的id是类名小写
2)@Service(服务存储)
3)@Repository(仓库存储)
4)@Component(组件存储)
5)@Configuration(配置存储)

4. 方法注解:

@Bean:将当前@Bean修饰方法的方法对象存储到Spring当中。

  1. 演示:
    2
    3

6. 相关问题

1)如果类名首字母是小写,要怎么从Spring中获取Bean?(默认id是首字母小写)

① 和首字母大写时是一样的,都是使用将类名首字母小写的方式来获取Bean对象的。
② 同样的方式:获取Spring对象(ApplicationContext/BeanFactory)、获取Bean对象(getBean(“id”,类名.class))、使用Bean。
③ 【注意:但是千万不要忘记加上类注解!!否则编译失败!】
④ 默认id是小写开头,当类名是小写字母开头时,id同样也是小写开头(也就是与类名相同),此时是可以正确输出结果的。

3

2)如果首字母和第二个字母都是大写,会怎么样?

① 当使用默认规则(id首字母小写)获取Bean对象的方法已经不适用了,会抛出NoSuchBeanDefinitionException异常
5

正确获取Bean的方式是id直接使用原类名就能成功获取到了。
6

3)项目中如果没有包目录,所有的类都写在java根路径下,那么要怎么存取Bean对象呢?

① 此时不管在xml的 base-package=""中配置空or其他路径都会出现NoSuchBeanDefinitionException错误,此时需要使用通配符。
通配符*表示匹配任意一个的,**表示匹配根路径以及根路径底下的所有子路径。
7
(但是执行速度巨慢,不建议使用!)
③ 使用通配符后可能会报错(不要忘记加上类注解):
8
④ 发现在添加了类注解之后还是报错, 此时解决方法:获取Spring对象的方法换为BeanFactory
9


7. 补充【结论、查看源码】

  1. 结论:当使用五大类注解时,默认情况下获取Bean对象id只需要将首字母小写即可;然而,当Bean对象首字母和第二个字母均是大写时,此时需要使用原类名才能正确获取到Bean对象。【五大类注解均适用!
  2. 注意:IDEA下按ctrl+r是查找替换当前文档内容,连续按两下shift是全局搜索。
  3. 在IDEA中进行方法跳转:ctrl+左键(查看源码时适用)
  4. 查看id命名规则方法:

连续shift -> 搜索beanName -> AnnotationBeanNameGenerator
10

-> buildDefaultBeanName跳转 -> decapitalize跳转 -> 定位当前类位置 11

-> 定位到rt.jar中(jdk的工具方法类) 12

-> 分析源代码 13
-> 小结
默认是首字母小写;如果一二个字母均是大写,就直接使用原类名就ok!


  1. 如果出现NoSuchBeanDefinitionException错误,要么是没有加注解,要么是id名字写错了;亦或者是配置xml时包名没有配对。

  2. 如果在spring-config.xml配置package的包下还有子目录也是ok的,可以访问到!


三)为什么要使用这么多类注解

  1. 为什么需要五个类注解?
    1)通过类注解可以了解当前类的用途(就类似:看到车牌就知道是哪个城市的车)
    2)功能有细微的不同:在Spring MVC/Spring Boot中有体现,等彼时再细讲。

  2. 五个类注解的用途:【重要!✨】
    1)@Controller(控制器):归属于业务逻辑层,用来控制用户的行为,它用来检查用户参数的有效性。
    2)@Sservice(服务):归属于服务层,调用持久化类实现相应的功能。【不直接和数据库交互,它类似于控制中心】
    3)@Repository(仓库):归属于持久层,是直接和数据库进行交互的。通常每一个表都会对应一个@Repository仓库类。
    4)@Configuration(配置):归属于配置层,是用来配置当前项目的一些信息。
    5)@Component(组件):归属于公共工具类,提供某些公共方法。
    13

  3. 五大类注解有什么关系?
    使用ctrl+左键 进入源码进行查看
    1)注:@interface是自定义注解类
    15
    2)【小结
    @Component是 @Controller / @Service / @Repository / @Configuration的父类

五大类有区别,但是具体在Spring MVC/ Spring Boot中细讲


四)方法注解 @Bean

  1. 方法注解@Bean实现一个类的 多次存到 Spring中,但是要注意方法注解是将 方法返回的对象 存到Spring中,所以一定要有 返回类型
  2. 举栗子:
    1) 方法注解(配合五大类使用)
    20
    2) 进行获取:
    ① 注意id默认是@Bean注解的方法的方法名
    注意:获取Spring对象的时候需要使用ApplicationContext,如果使用BeanFactory的话就会报错!

BeanFactory的话就会报错:原因可能是BeanFactory出现的太早,导致后续在jdk1.5之后出现的注解不兼容;读xml是没有问题的,但是读bean就可能会存在问题。

21
22


  1. 注意事项:方法注解@Bean一定要配合五大类去使用! 否则是无效的方法注解。
    (主要是考虑性能问题,配合类注解更容易找到对应的路径)

  2. Bean是支持设置name属性的,便于区分。并且是可以设置多个name的
    23
    注意:如果给@Bean设置name属性后,id就不能再使用默认的方法名了!!


二、获取Bean对象(对象装配)

  1. 对象装配(对象注入)的实现方式有以下三种:
    1)属性注入
    2)构造方法注入
    3)Setter注入

  2. 以上所有的注入方法都要与类注解搭配使用! 其中构造方法注入如果只有一个构造方法的话@Autowired是可以省略的。


1. 属性注入

  1. @Autowired
    直接进行声明就行

  2. 一定要进行类注释!否则会编译错误!
    30


2. 构造方法注入(官方推荐写法)

  1. 直接将Bean对象作为构造方法的参数参数传入

  2. 依旧要使用@Autowired(构造方法上)类注解的搭配!
    31

  3. 注:如果当前类中只有一个构造方法,@Autowired是可以省略的。但是一个类中如果有多个构造方法就不可省略。


3. Setter注入

  1. 在设置setter方法的时候要加上 @Autowired注解,并且在类上也要加上类注解
  2. 在设置setter方法的时候不加上@Autowired注解就会报错。
    32

4. 三种注入方式的区别【经典面试题】

请说说属性注入、构造方法注入和Setter注入的区别?
【各自优缺点】
1)属性注入

① 写法简单;
② 但是通用性不好,它只能运行在IoC容器下,如果是非IoC容器就会出现问题,并且只有在使⽤的时候才会出现 NPE(空指针异常)。
(实际开发中常用)

2)Setter注入

① 早期Spring版本推荐的写法;
② 但是Setter注入的通用性没有构造方法注入通用(但是高于属性注入)。

3)构造方法注入

① 通用性更好,它能确保使用注入对象之前此对象一定已经注入,可以保证注入的类不为空(因为是在构造方法中,在实例化时就注入);
② 但是当构造方法注入参数过多就会比较臃肿时,此时开发者就要检查自己所写的代码是否符合“单一设计原则”的规范了。
此注入方式也是Spring后期版本中推荐的注入方式。

单一设计原则SRP:它规定一个类只有一个发生变化的原因。如果多于一个导致类变更的原因,则违反了SRP。


5. @Resource:另⼀种注⼊关键字

  1. @Resource注入关键字类似于@Autowired,使用方法很像;但是有细微的差别。
  2. 在属性注入和Setter注入中,@Resource可以替换@Autowired,程序可以正常运行。
  3. 但是:构造方法注入只能使用@Autowired,使用@Resource直接报错。
  4. 小结@Resource支持属性注入和Setter注入,但是不支持构造方法注入。
  5. 注:@Resource是jdk提供的,而@Autowired是Spring框架提供的。

33


6. @Resource和@Autowired的区别【经典面试题】

注意区别:
① 对象注入有几种方式:3种(属性、构造方法和Setter注入)
② 对象注入的方法:2种(@Resource和@Autowired)
不确定时直接与面试官沟通确认是问哪一种

1)相同点:都可以实现将一个对象注入到一个类中。(类的对象;有@Bean修饰方法的话,Spring就是存储返回类型,对象名就对应方法名/自定义名
2)不同点:
出身不同:@Resource来自于JDK(java亲儿子),@Autowired是Spring框架提供的。
用法不同:@Autowired 支持属性注入、构造方法注入和Setter注入,@Resource不支持构造方法注入。
支持的参数不同:@Resource支持更多的参数设置,如name、type等设置,而@Autowired只支持required参数设置。
(通常情况下,我们会使用@Autowired)


7. 同⼀类型多个 @Bean 报错

  1. 同一个类中出现多个@Bean(类型上有类注解)
    35

  2. 使用属性注入获取Bean对象(不要忘记类注解)36

  3. 获取到的Bean对象错误
    37

  4. 此时:同⼀个类型,多个 bean 的解决⽅案有以下两个
    使⽤ @Resource(name=“xxx”) 定义
    使⽤ @Qualifier 注解定义名称(搭配@Autowired)

  5. 使用示例:
    1)使⽤ @Resource(name="xxx") 定义具体的方法。
    注意name和@Bean的方法名保持一致!
    38

2)使⽤ @Qualifier 注解定义名称。
@Qualifier(value = “xxx”)中的value也是和@Bean修饰的方法名保持一致!
@Qualifier必须和@Autowired配合使用,且只能是@Autowired,不能是@Resource 。
39


小结

  1. 五大类注解及其关系
  2. 方法注解必须配合类注解
  3. Bean命名规则(id)
  4. 从Spring中获取Bean对象(属性、Setter、构造函数注入)
  5. 三种注入方式的区别(相同点+不同点)
  6. 注入关键字(2个)
  7. @Autowired 和 @Resource 区别(出身、用法、支持的参数)
  8. 解决同⼀类型多个 Bean 的报错(2个方法)

在这里插入图片描述

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

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

相关文章

ROS2机器人编程简述humble-第二章-DEVELOPING THE FIRST NODE .2

0.1ROS2机器人编程简述新书推荐-A Concise Introduction to Robot Programming with ROS21.1ROS2机器人编程简述humble-第一章-Introduction2.1ROS2机器人编程简述humble-第二章-First Steps with ROS2 .12.2主要内容是全手工创建一个最简单的自定义节点&#xff0c;其实没啥具…

IB学生必看的时间表(二)

上期谈到在IB预科课程的第一个学年下学期&#xff0c;便要开始作报读大学的准备&#xff0c;到底为什么&#xff1f; 暑假不容松懈 现在来到放暑假了。虽说不用上课&#xff0c;学生没有了学习压力&#xff0c;但就以下三方面来看&#xff0c;学生还是要继续投放心力。 首先&am…

Unity 之 Addressable可寻址系统 -- 代码加载介绍 -- 进阶(一)

Unity 之 可寻址系统 -- 代码加载介绍 -- 进阶&#xff08;一&#xff09;一&#xff0c;可寻址系统代码加载1.1 回调形式1.2 异步等待1.3 面板赋值1.4 同步加载二&#xff0c;可寻址系统分标签加载2.1 场景搭建2.2 代码示例2.3 效果展示三&#xff0c;代码加载可寻址的解释概述…

Cadence OrCAD: 跨页符和电源符号命名优先级的一个小问题

Cadence OrCAD: 跨页符和电源符号命名优先级的一个小问题 遇到的问题 最近项目中&#xff0c;有个电源需要做负载端的反馈&#xff0c;类似下图的signal1和signal1N&#xff0c;反馈使用类似伪差分线&#xff0c;把电压信号和负载端的GND都连到DC-DC控制器。DC-DC对应的反馈引…

字节跳动青训营--前端day1

文章目录前言一、 前端1 前端的技术栈2. 前端的边界3. 前端的关注点二、 HTML1. HTML常用标签及语义化2. HTML 语法3. 谁在使用我们写的HTML前言 仅以此文章记录学习历程 一、 前端 解决GUI人机交互问题 1 前端的技术栈 2. 前端的边界 nodejs–服务器端应用 electron… --客…

【数据结构】6.1 图的基本概念和术语

文章目录前言6.1 图的定义和术语前言 图是一种比线性表和树更为复杂的数据结构。 在线性结构中&#xff0c;结点之间的关系属于一个对一个&#xff1b;数据元素之间有着线性关系&#xff0c;每个数据元素只有一个直接前趋和一个直接后继&#xff0c; 在树形结构中&#xff0c;…

算法设计与分析课程

算法的由来 算法的定义 算法的定义&#xff1a;给定计算问题&#xff0c;算法是一系列良定义的计算步骤&#xff0c;逐一执行计算步骤可得到预期的输出。 良定义&#xff1a;定义明确无歧义 计算步骤&#xff1a;计算机可以实现的指令 有了良定义的计算步骤&#xff0c;计算机就…

Java基础篇01-运算符的使用

01| Java中的数据类型 ) 1. 数值型&#xff1a; 序号类型空间占用说明最小值最大值默认值优缺点对比举例1byte8位有符号整数-128(-2^7)127 (2^7-1)0byte 类型用在大型数组中节约空间&#xff0c;主要代替整数&#xff0c;因为 byte 变量占用的空间只有 int 类型的四分之一by…

6、Denoising Diffusion Probabilistic Models(扩散模型)

简介 主页&#xff1a;https://hojonathanho.github.io/diffusion/ 扩散模型 &#xff08;diffusion models&#xff09;是深度生成模型中新的SOTA。 扩散模型在图片生成任务中超越了原SOTA&#xff1a;GAN&#xff0c;并且在诸多应用领域都有出色的表现&#xff0c;如计算机…

【docker概念和实践 1】 基本概念和组成原理

一、说明 初学Docker就一个字&#xff1a;乱&#xff01;这是因为Docker是一个庞大体系&#xff0c;初学时不了解全貌&#xff0c;处于“盲人摸象”状态&#xff0c;因不能通晓要领&#xff0c;学了一点&#xff0c;过后就忘了。而了解Docker全貌并非易事&#xff0c;官方文档也…

前端学习记录-Javascript

pink JS基础语法JavaScript核心教程阮一峰JS基础 JS基础语法 初识JS JS三种书写位置&#xff1a;行内、内嵌、引入式。单行注释 ctrl/ 多行注释 shift alt a输入输出语句 声明变量 var age;变量命名规范&#xff1a;字母、数字、下划线、美元符号组成&#xff0c;区分大小写…

质量体系搭建

测试团队的发展历程 初期阶段 特点&#xff1a;提供“保姆式”服务&#xff0c;以发现BUG为主要任务。 工作主要&#xff1a;以功能测试、兼容行测试为主的手工测试&#xff0c;每天进行大量的、重复性的工作&#xff0c;即便如此依然会有遗漏。刚起步的测试团队基本处于这个阶…

LeetCode分类刷题----哈希表篇

哈希表哈希表1.有效的字母异位词242.有效的字母异位词383.赎金信49.字母异位词分组438.找到字符串中所有字母异位词2.两个数组的交集349.两个数组的交集350.两个数组的交集||3.快乐数202202.快乐数4.两数之和1.两数之和5.四数相加454.四数相加||6.三数之和15.三数之和7.四数之和…

ARM 实时时钟 RTC

一、何为实时时钟 (1) real time clock&#xff0c;真实时间&#xff0c;就是所谓的xx年x月x日x时x分x秒星期x. (2) RTC是 SoC 中一个内部外设&#xff0c;RTC 有自己独立的晶振提供 RTC 时钟源&#xff08;32.768KHz&#xff09;&#xff0c;内部有一些寄存器用来记录时间&am…

微信小程序登陆,后端接口实现 - springboot

登录流程 1、通过调用wx.login获取登录凭证&#xff08;code&#xff09; uni-app通过调用uni.login 2、前端将code提交给服务器&#xff0c;springboot访问 auth.code2Session&#xff0c;使用 code 换取 openid、unionid、session_key 等信息。 3、完成登录操作&#xff0…

数学计算-C语言实现

任务描述 计算如下公式的值: 其中π=3.1415926 本关知识 C语言常用数学函数及其用法 在使用C语言数学函数时候,应该在该源文件中使用以下命令行包含库文件: #include <math.h> 或 #include "math.h" 本题中用到的C语言数学函数如下: abs函数: 求整型…

Pytorch模型自定义数据集训练流程

文章目录Pytorch模型自定义数据集训练流程1、任务描述2、导入各种需要用到的包3、分割数据集4、将数据转成pytorch标准的DataLoader输入格式5、导入预训练模型&#xff0c;并修改分类层6、开始模型训练7、利用训好的模型做预测Pytorch模型自定义数据集训练流程 我们以kaggle竞…

交互与前端20 APIFunc.DataBase监控

说明 APIFunc.DataBase的第一版有一个监控一直在做agg,造成数据库的无谓消耗,所以一定得修补。在修补的同时,做了一些主要的修改: 1 【自增ID】给Mongo的In和Out增加了数据的自动编号和随机数生成。2 【使用缓存】通过Redis缓存,极大的的减轻了Mongo(主库)的负担这样,使得…

Kruskal重构树学习笔记(C++)

Kruskal重构树学习笔记 提示&#xff1a; 学习Kruskal重构树之前建议先了解一下Kruskal算法&#xff0c;虽然不了解这个影响不会很大 但一定要了解一下并查集的算法 接下来如果想要应用Kruskal重构树&#xff0c;一定要了解一下LCA算法 什么是Kruskal重构树 这里先简单说…

exec函数族详解

文章目录exec介绍exec族execl函数execlp函数execv函数exec介绍 通过命令查看帮助&#xff1a;man 3 exec exec 函数族的作用是根据指定的文件名找到可执行文件&#xff0c;并用它来取代调用进程的内容&#xff0c;换句话说&#xff0c;就是在调用进程内部执行一个可执行文件。…