Spring的存储与获取Bean

news2024/11/29 0:42:45

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.coloradmin.cn/o/646470.html

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

相关文章

FTL没有映射,跟发工资没有钱有什么区别

大家好&#xff0c;我是五月。 前言 FTL&#xff08;Flash Translation Layer&#xff09;&#xff0c;即闪存转换层&#xff0c;是各种存储设备的核心算法&#xff0c;作用是将Host传下来的逻辑地址转换成物理地址&#xff0c;也就是映射。 地址映射是FTL最原始最基本的功能…

Pytest教程__简介与安装(1)

一、Pytest简介 pytest是python的一种单元测试框架&#xff0c;与python自带的unittest测试框架类似&#xff0c;但更灵活。 官方网站优点简介&#xff1a; 非常容易上手&#xff0c;入门简单&#xff0c;文档丰富&#xff0c;文档中有很多实例可以参考能够支持简单的单元测试…

【Qt】Ubuntu安装GCC9.3.0版本的Qt5.15.5

目录 一、安装GCC9.3.0 1.下载GCC9.3.0源码 2.获取依赖项的包 3.生成Makefile文件 4.编译并安装 5.生成软链接 6. 查看GCC版本 二、安装Qt 1.下载Qt安装包 2.创建Qt项目并运行 一、安装GCC9.3.0 1.下载GCC9.3.0源码 https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3…

药物靶点信息数据库有哪些?都有哪些特点?

药物靶点信息数据库的应用不仅能够高效地扩大靶点信息获取&#xff0c;而且能深化科研人员对于靶点的认识&#xff0c;从而服务于新靶点发现、药物筛选、药物设计、疾病治疗及药理学机制的研究等领域。 药物靶点可以分为受体、酶、离子通道、DNA、激素与生长因子等几种类型。随…

linux服务器上,docker安装nginx

如果出现 Using default tag: latest Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/create?fromImagenginx&taglatest": dial unix /va…

不衔接的两个视频能拼在一起吗?怎么把视频拼接起来?

怎么把视频拼接起来&#xff1f;相信大家在平时刷小视频的时候&#xff0c;都看到过视频合集&#xff0c;例如搞笑视频合集、综艺片段合集、变装合集等等。其实这些视频合集都是通过视频拼接来完成的&#xff0c;只需短短几分钟就能通过这些视频获得愉悦体验&#xff0c;非常适…

一学就会-----删除链表中的重复节点

文章目录 题目描述思路一代码示例思路二代码示例 题目描述 在一个排序的链表中&#xff0c;存在重复的结点&#xff0c;请删除该链表中重复的结点&#xff0c;重复的结点不保留&#xff0c;返回链表头指针。 图片示例&#xff1a; 思路一 解决该问题较简单&#xff0c;且在…

光纤跳线性能测试科普

光纤跳线是一种用于连接光纤设备或光纤网络的光学传输线路&#xff0c;它由两个光纤连接器和一段光纤组成。光纤跳线的质量直接影响着光信号的传输效率和稳定性&#xff0c;因此需要进行一些测试来保证其性能。 一、测试类型 光纤跳线性能测试主要有以下四种&#xff1a; 极性…

【基于容器的部署、扩展和管理】3.10 云原生容器运行时环境和配置管理

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【3.1 容器编排系统和Kubernetes集群的构建】 第三章&#xff1a;【3.2 基于容器的应用程序部署和升级】 第三章&#xff1a;【3.3 自动…

运维圣经:Webshell应急响应指南

目录 Webshell简介 Webshell检测手段 Webshell应急响应指南 一. Webshell排查 二. 确定入侵时间 三. Web日志分析 四. 漏洞分析 五. 漏洞复现 六. 清除Webshell并修复漏洞 七. Webshell防御方法 Webshell简介 Webshell通常指以JSP、ASP、 PHP等网页脚本文件形式存在…

kubesphere jenkins 构建java项目报错Could not parse metadata

kubesphere jenkins 构建java项目报错Could not parse metadata 问题描述&#xff1a; [ERROR] Failed to execute goal org.apache.maven.plugins:maven-install-plugin:2.4:install (default-install) on project common-plugin-starter: Failed to install metadata com.n…

struct | 详解C语言结构体

结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合&#xff0c;也叫结构。 结构体和其他类型基础数据类型一样&#xff0c;例如 int 类型&#xff0c;char类型&#xff1b;只不过结构体可以做成你想要的数据类型&#xff0c;以方便日后的使用。 在实际项目…

STM32单片机(六)TIM定时器 -> 第二节:TIM定时中断练习(定时器定时中断和定时器外部时钟)

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

vivado:引脚已约束但是报错

一、问题引入 报错信息如下&#xff1a; [DRC UCIO-1] Unconstrained Logical Port: 3 out of 3 logical ports have no user assigned specific location constraint (LOC). This may cause I/O contention or incompatibility with the board power or connectivity affect…

msvc编译qt源码(qt6之前版本)

配置环境 根据源码里的readme&#xff08;D:\Qt\Qt5.9.9\5.9.9\Src\readme&#xff09;安装对应的依赖环境&#xff0c;如果是整个源码编译必须都安装 Qt for Windows - Requirements | Qt 5.15 Qt for Windows - Building from Source | Qt 5.15 Qt WebEngine Platform Not…

day02--java基础编程:变量,数据类型,类型转换,运算规则,运算符,分支结构,循环(随机数),方法,重载,可变参数,递归,数组,冒泡排序

1 Day02–变量数据类型类型转换 1.1 前言 1.1.1 标识符 可以简单的理解为一个名字。在Java中&#xff0c;我们需要标识代码的很多元素&#xff0c;包括包名、类名、方法、字段、变量等。我们选择的名称就称为标识符&#xff0c;并且遵循以下规则&#xff1a; A.标识符可以由…

docker-compose部署单点apm链路追踪

一.docker-compose 安装下载 1、登入 GitHub &#xff0c;找到对应版本 curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-uname -s-uname -m -o /usr/local/bin/docker-compose2、将下载后的文件放到 /usr/local/bin 目录下&#xff0c;并…

客服部2023年中总结|用心服务,稳步提升用户体验

一、人工智能相辅相成&#xff1a;提升服务效能 2023年上半年&#xff0c;CSDN人工客服处理客诉总量为26859条&#xff0c;同比去年客诉量38695&#xff0c;下降30.59%&#xff1b;问题解决效率为72min&#xff0c;同比下降19%。 客诉量TOP5: 付费专栏质量问题退费博文审核未…

一文吃透低代码平台的衍生历程、优势及未来趋势

一、低代码概念 低代码开发平台是一种无需编码或者只需要少量代码即可快速生成应用程序的开发平台&#xff0c;通过可视化进行应用程序开发的方法&#xff0c;让不同经验水平的开发人员可以通过图形化的用户界面&#xff0c;使用拖拽组件和模型驱动的逻辑来创建网页和移动应用程…

Unity3D:场景可见性

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 场景可见性 Unity 的场景可见性控件可用于在 Scene 视图中快速隐藏和显示游戏对象&#xff0c;而无需更改它们在游戏中的可见性。 这可用于处理难以查看和选择特定游戏对象的大型或…