Spring的存储与获取Bean

Spring的存储与获取Bean

  • 🔎Spring—存储Bean
    • 配置扫描路径
    • 利用类注解进行存储
      • 添加注解存储Bean
      • 关于Id
      • 为什么需要五个类注解
      • 类注解之间的关系
    • 利用方法注解进行存储
      • 关于Id
  • 🔎Spring—获取Bean
    • 属性注入
    • Set注入
    • 构造方法注入
    • 总结(Spring的注入方式? 它们之间的区别?)
    • @Resource
      • 对比@Resource与@Autowired
      • Tips
  • 🔎结尾

关于 Spring 的创建及简单的使用
可以参考这篇文章

🔎Spring—存储Bean


之前的存储方式是利用<bean id="" class=""></bean>进行存储

但这种方式存在一个弊端

即需要存储的 Bean 过多时, 手动添加过于繁琐

利用注解可以有效规避这种情况

  • 添加注解存储 Bean
    • 类注解
      • @Controller: 控制器存储
      • @Service: 服务存储
      • @Repository: 仓库存储
      • @Component: 组件存储
      • @Configuration: 配置存储
    • 方法注解
      • @Bean: 对象存储(需搭配类注解一同使用)

配置扫描路径


添加如下代码至xml文件中

<content:component-scan base-package=""></content:component-scan>

base-package=""
引号中填写的是扫描路径

完整代码

<?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=""></content:component-scan></beans>

如图
base-package="com.demo"
扫描路径为com包下的demo包下的全部

在这里插入图片描述

所有的类都写在 Java 根路径下, 没有目录, 该如何存储 / 获取 Bean🍭

(了解即可, 通常不会这么做)

base-package="**"

将扫描路径更改为根目录下的全部

*表示根目录
**表示根目录下的全部

利用类注解进行存储


在 Spring Core 中, 类注解之间的区别不大

添加注解存储Bean


添加 @Controller 注解存储 Bean

在这里插入图片描述

获取 Bean

在这里插入图片描述

添加 @Service 注解存储 Bean

在这里插入图片描述

获取 Bean

在这里插入图片描述

添加 @Repository 注解存储 Bean

在这里插入图片描述

获取 Bean

在这里插入图片描述

添加 @Component 注解存储 Bean

在这里插入图片描述

获取 Bean

在这里插入图片描述

添加 @Configuration 注解存储 Bean

在这里插入图片描述

获取 Bean

在这里插入图片描述

关于Id


通过添加注解的方式存储 Bean, 获取 Bean 时的 Id 该如何命名🍭

  • 当类名为标准驼峰命名时, 将类名的首字母小写, 其余字母不变
    • (例如类名为UserInfo, 其对应的IduserInfo)
  • 当类名的首字母为小写时, 不做改变
    • (例如类名为userInfo, 其对应的IduserInfo)
  • 当类名的首字母和第二个字母均为大写, 不做改变
    • (例如类名为UInfo, 其对应的IdUInfo)

源码分析🍭

  • AnnotationBeanNameGenerator
    • Annotation, 注解
    • BeanName, 对象名
    • Generator, 生成
    • Annotation BeanName Generator, 生成对象名注解

在这里插入图片描述

找到AnnotationBeanNameGeneratorgenerateBeanName()
点击buildDefaultBeanName()

在这里插入图片描述

点击buildDefaultBeanName()

在这里插入图片描述

点击decapitalize()

在这里插入图片描述

找到最终的调用方法

在这里插入图片描述

分析这段代码

public static String decapitalize(String name) {if (name == null || name.length() == 0) {return name;}if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&Character.isUpperCase(name.charAt(0))){return name;}char chars[] = name.toCharArray();chars[0] = Character.toLowerCase(chars[0]);return new String(chars);
}
  • if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && Character.isUpperCase(name.charAt(0))){ return name; }

如果长度 > 1 且第 1 个字符与第 0 个字符均是大写, 返回该字符串

(当类名的首字母和第二个字母均为大写, 不做改变)

  • chars[0] = Character.toLowerCase(chars[0]);

将第 0 个字符变为小写

(当类名为标准驼峰命名时, 将类名的首字母小写, 其余字母不变)
(当类名的首字母为小写时, 不做改变)

为什么需要五个类注解


既然都可以通过添加类注解的方式存储 Bean
那为何还需要五个类注解呢?

  1. 通过类注解可以了解当前类的用途
  2. 具体的功能存在差异

举个栗子🌰

通过车牌可以了解是哪里的车🚗, 例如 京 → 北京, 津 → 天津
(通过类注解可以了解当前类的用途)

类注解的用途🍭

  1. @Controller(控制器), 归属于业务逻辑层, 用于校验用户参数的有效性(控制用户的行为)
  2. @Service(服务), 归属于服务层, 调用持久化类实现相应的功能(不直接与数据库交互, 类似于控制中心)
  3. @Repository(仓库), 归属于持久层, 直接与数据库交互(通常一张表对应一个 @Repository)
  4. @Configuration(配置), 归属于配置层, 用于配置当前项目的一些信息
  5. @Component(组件), 归属于公共工具类, 提供某些公共方法

举个栗子🌰

滑稽老哥家中失窃, 选择报警
接警员判断情况是否属实, 避免小孩子的恶作剧
(@Controller)

警局根据接警员的信息派出一些警察负责跟进
(@Service)

出警的警察负责这一起案件
(@Repository)

在这里插入图片描述

类注解之间的关系


@Component 是 @Controller, @Service, @Repository, @Configuration 的父类

在这里插入图片描述

利用方法注解进行存储


方法注解需搭配类注解一同使用
(目的是为了提高效率)

新建一个 Student 类

在这里插入图片描述

新建一个 StudentBeans 类

为 getStu() 添加方法注解(@Bean)
为 StudentBeans 添加类注解(@Component)

在这里插入图片描述

关于Id


  • 默认情况下 getBean() 对应的 Id 为方法名
  • @Bean 后可以跟 name
    • (例如 @Bean(name = {"s1", "s2"}))
  • 当 @Bean 后添加了 name 时, 所对应的 Id 只能为 name 名, 不允许设置为方法名

默认情况下 getBean() 对应的 Id 为方法名

在这里插入图片描述

@Bean 后可以跟 name

在这里插入图片描述

🔎Spring—获取Bean


从 Spring 中获取 Bean 也称为对象装配, 对象注入

对象装配(对象注入)的方式可以划分为 3 种

  • 属性注入
  • Set 注入
  • 构造方法注入

属性注入


在这里插入图片描述

属性注入的效果等同于赋值

举个栗子🌰

@Autowired
private StudentService studentService;private int num = 10;

StudentService studentService利用属性注入, 由 Spring 框架赋值
int num未利用属性注入, 由程序员赋值

综上, 再次说明了 Spring 是一个包含众多工具方法的 IOC 容器
(IOC → 控制反转)

属性注入的优点🍂

  • 实现简单

属性注入的缺点🍂

  • 不能注入不可变对象(final 修饰)
  • 只适用于 IOC 容器
  • 更容易违背单一设计原则

不能注入不可变对象(final 修饰)

final 修饰的对象有 2 种赋值方式

  1. 直接赋值
  2. 在构造方法中赋值

只适用于 IOC 容器

@Autowired 来自于 Spring
Spring 是一个包含众多工具方法的 IOC 容器
因此只适用于 IOC 容器

更容易违背单一设计原则

属性注入的方式实现简单
因此也更容易将其他无关的对象一并注入
也就更容易违背单一设计原则

Set注入


在这里插入图片描述

Set 注入的优点🍂

  • 更符合单一设计原则

Set 注入的缺点🍂

  • 不能注入不可变对象(final 修饰)
  • 注入的对象可被修改

更符合单一设计原则

Set 注入的实现方式相比于属性注入较复杂
因此相较于属性注入也就避免了将其他无关的对象一并注入的情况
(更符合单一设计原则)

不能注入不可变对象(final 修饰)

final 修饰的对象有 2 种赋值方式

  1. 直接赋值
  2. 在构造方法中赋值

注入的对象可被修改

Set 注入相较于属性注入更危险!

属性注入的对象也可被修改
但 Set 注入除通过属性注入的方式修改注入的对象
也可通过 set() 方法修改注入的对象

set() 方法既可以被 Spring 调用
也可以被其他对象调用

构造方法注入


在这里插入图片描述

注意

  1. 当只存在一个构造方法时, @Autowired 可省略
  2. 当存在多个构造方法时, @Autowired 不可省略

构造方法注入的优点🍂

  • 能注入不可变对象(final 修饰)
  • 注入的对象不可被修改
    • final 修饰
    • 构造方法随着类的加载只执行一次
  • 注入的对象会被完全初始化(类加载时就会将对象进行初始化, 当执行其他方法时, 对象已被初始化 → 构造方法的机制)
  • 通用性更好(任何一个类都会有构造方法)

构造方法注入的缺点🍂

  • 实现方式不如属性注入简单

总结(Spring的注入方式? 它们之间的区别?)

在这里插入图片描述

@Resource


  • @Resource
    • 可以实现属性注入
    • 可以实现 Set 注入
    • 不可以实现构造方法注入

使用 @Resource 实现属性注入

在这里插入图片描述

使用 @Resource 实现 Set 注入

在这里插入图片描述

使用 @Resource 不能实现构造方法注入

在这里插入图片描述

在这里插入图片描述

对比@Resource与@Autowired

在这里插入图片描述

来源不同🍭

@Resource

在这里插入图片描述

在这里插入图片描述

@Autowired

在这里插入图片描述

支持参数不同🍭

@Resource

在这里插入图片描述

@Autowired

在这里插入图片描述

Tips


存在返回同一个类型的多个方法时

在这里插入图片描述

利用@Resource(name = "")可以将其进行区分

在这里插入图片描述

@Autowired 无法设置 name

只能填写对应的对象

在这里插入图片描述

如果想写成 student 形式
需搭配@Qualifier()进行使用, 括号中填写的内容为对应的对象

在这里插入图片描述

🔎结尾

创作不易,如果对您有帮助,希望您能点个免费的赞👍
大家有什么不太理解的,可以私信或者评论区留言,一起加油

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

An unexpected connection driver error occured

安装下载好rabbitmq&#xff0c;我在springboot整合mq&#xff0c;启动的时候报错了 An unexpected connection driver error occured 后来又报 Failed to check/redeclare auto-delete queue(s). 综合就是连接问题&#xff0c;端口有问题 我试过添加账户&#xff0c;提高权限&…

【架构】领域驱动设计(DDD)的几种典型架构介绍

文章目录 前言一、专业术语二、架构演变三、限界上下文四、领域驱动设计的四重边界五、整洁分层架构六、六边形架构七、洋葱架构总结 前言 我们生活中都听说了DDD&#xff0c;也了解了DDD&#xff0c;那么怎么将一个新项目从头开始按照DDD的过程进行划分与架构设计呢&#xff…

解决页面等比缩放问题

近些年可视化数据大屏技术早已成熟&#xff0c;在市场上相关技术也是五花八门&#xff1b;通常情况是自行开发&#xff0c;要不找技术比较成熟大厂定制&#xff0c;或者使用较成熟的低代码平台实现。 技术门槛比较低&#xff0c;不过在数据大屏项目实施过程中会发现&#xff0c…

深入理解深度学习——BERT派生模型:BART(Bidirectional and Auto-Regressive Transformers)

分类目录&#xff1a;《深入理解深度学习》总目录 UniLM和XLNet都尝试在一定程度上融合BERT的双向编码思想&#xff0c;以及GPT的单向编码思想&#xff0c;同时兼具自编码的语义理解能力和自回归的文本生成能力。由脸书公司提出的BART&#xff08;Bidirectional and Auto-Regre…

CDH 之 Hive 中文乱码平定通用法则

一、乱象 1.1 中文注释乱码 hive> DESCRIBE test; OK # col_name data_type comment id string ??ID ?? pcs string ????? …

uniapp中uni-popup的用法——实例讲解

uni-pop弹出层组件&#xff0c;在应用中弹出一个消息提示窗口、提示框等,可以设置弹出层的位置&#xff0c;是中间、底部、还是顶部。 如下图效果所示&#xff1a;白色区域则为弹出的pop层。 一、 创建一个自定义组件&#xff1a; 1.项目中安装下载uni-pop插件。 2.把pop内容…

C# wpf 附加属性实现任意控件拖动调整大小

摘自这里 https://blog.csdn.net/u013113678/article/details/121719278 调试效果如下 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using Syst…

CISSP证书考试难度大吗?本文教你如何轻松拿下CISSP

主题&#xff1a;CISSP含金量、CISSP考试经验、CISSP备考、CISSP考试大纲 CISSP含金量高 CISSP注册信息系统安全师认证是信息安全领域被全球广泛认可的IT安全认证&#xff0c;一直以来被誉为业界的“金牌标准”。CISSP认证不仅是对个人信息安全专业知识的客观评估&#xff0c…

OpenCV 笔记_5

文章目录 笔记_5特征点匹配DMatch 存放匹配结果DescriptorMatcher::match 特征点描述子&#xff08;一对一&#xff09;匹配DescriptorMatcher::knnMatch 特征点描述子&#xff08;一对多&#xff09;匹配DescriptorMatcher::radiusMatch 特征点描述子&#xff08;一对多&#…

VS2022编译运行VS2015的项目

最近新装了VisualStudio2022&#xff0c;有一些VS2015老的项目需要运行&#xff0c;但不想再安装VS2015&#xff0c;就想能否直接在VS2022编译运行&#xff0c;研究一下发现可行&#xff0c;记录一下。 1. 直接升级VS2015项目到2022使用windows sdk 10.0 发现老代码里的一些语…

MedLSAM:定位和分割任何3D医学图像模型

文章目录 MedLSAM: Localize and Segment Anything Model for 3D Medical Images摘要本文方法模型学习过程模型推理过程 实验结果 MedLSAM: Localize and Segment Anything Model for 3D Medical Images 摘要 SAM (Segment Anything Model)是近年来出现的一种具有开创性的图像…

Linux--时间相关的指令:date、cal

一、data显示 date 指定格式显示时间&#xff1a; date %Y:%m:%d date 用法&#xff1a; date [OPTION]... [FORMAT] 1.在显示方面&#xff0c;使用者可以设定欲显示的格式&#xff0c;格式设定为一个加号后接数个标记&#xff0c;其中常用的标记列表如下 %H : 小时(00..2…