Java【Spring】使用注解, 更简单的存储和获取 Bean

文章目录

  • 前言
  • 一、存储 Bean
    • 1, 配置文件
    • 2, 五大类注解
      • Bean 的命名规则
    • 3, 方法注解
      • Bean 的命名规则
  • 二、获取 Bean
    • 1, 属性注入
    • 2, Setter 注入
    • 3, 构造方法注入
    • 4, @Autowired 和 @Resource 的区别
    • 5, 同一个类型的多个 Bean 注入问题
  • 总结


前言

各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你:
📕 JavaSE基础: 基础语法, 类和对象, 封装继承多态, 接口, 综合小练习图书管理系统等
📗 Java数据结构: 顺序表, 链表, 堆, 二叉树, 二叉搜索树, 哈希表等
📘 JavaEE初阶: 多线程, 网络编程, TCP/IP协议, HTTP协议, Tomcat, Servlet, Linux, JVM等(正在持续更新)

Spring 中有很多注解, 来帮助我们更加方便, 高效的编写代码, 本篇介绍存储和获取 Bean 时使用到的注解
在这里插入图片描述


提示:是正在努力进步的小菜鸟一只,如有大佬发现文章欠佳之处欢迎批评指点~ 废话不多说,直接上干货!

一、存储 Bean

上篇文章 介绍了基本的存储和获取 Bean 的方式, 如果按照上篇文章介绍的方式存储Bean, 那么每存储一个 Bean 就需要在配置文件中写一行标签, 十分麻烦, 其实有一种更方便的方式, 我们可以配置存储对象的扫描包路径, 只有被配置的包下的所有类, 并且添加了注解 才能被正确的识别并保存到 Spring 中

1, 配置文件

<?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"></content:component-scan>
</beans>
  • resources 目录下新建一个 .xml 文件, 把上述代码拷贝到其中
    在这里插入图片描述
    指定了要扫描的包之后, 只有这个包, 以及这个包下面的子包中的代码, 添加了注解之后才能生效

2, 五大类注解

类注解(加在类上的注解)有五个:@Controller、@Service、@Repository、@Component、@Configuration

  • 使用 @Controller, 新建一个 UserController 类
    在这里插入图片描述

  • 使用 @Service, 新建一个 UserService 类
    在这里插入图片描述

  • 使用 @Repository, 新建一个 UserRepository 类
    在这里插入图片描述

  • 使用 @Component, 新建一个 UserComponent 类
    在这里插入图片描述

  • 使用 @Configuration, 新建一个 UserConfiguration 类
    在这里插入图片描述

  • 在启动类中使用 ApplicationContext 获取上下文对象, 使用 getBean 方法获取并使用刚刚存储的五个 Bean
    在这里插入图片描述

  • 观察执行结果, 是否都成功的存储了
    在这里插入图片描述


综上, 使用这五个类注解确实可以更方便的存储 Bean, 不需要再每存储一个就写一行配置标签, 那为什么要有五个呢? 一个不够吗? 这些注解有什么作用?

这五个注解分别标识了不同的作用, 看到这个注解就知道这个类是用来干什么的 :
@Controller 标识了业务逻辑层
@Service 标识了服务层
@Repository 标识了持久层
@Component 标识了组件层
@Configuration 标识了配置层

以下是阿里的工程分层调用流程 :

在这里插入图片描述

在真实的项目中也是需要按照大致的流程来分层管理代码模块


Bean 的命名规则

我们只是在配置文件中指定了要扫描的包路径, 并没有指定要存储的 Bean 的名称, 那凭什么根据下面代码中标出的这些命名就能正确找到 Bean 呢?

在这里插入图片描述

  • 默认情况下, Bean 的名称就是类名的小驼峰形式, 比如 : 类名是 UserController, Bean 的名称默认就是 userController

  • 但是!!! 如果类名的第一个字母和第二个字母都是大写, 比如: ABC, 那么 Bean 的名称就是 ABC(原类名) 而不是 aBC
    在这里插入图片描述
    如果 Bean 的名称是 aBC 无法存储
    在这里插入图片描述
    如果 Bean 的名称是 ABC 可以存储
    在这里插入图片描述

所以只有 不满足类名的前两个字母都是大写 的情况下, Bean 的默认命名是小驼峰形式, 否则就是原类名

当然也可以手动命名, 这些类注解都可以设置一个 Value 参数, 如图 :
在这里插入图片描述
在这里插入图片描述


3, 方法注解

方法注解 @Bean 是修饰在一个方法上, 那怎么能存储 Bean(类对象) 呢? 其实是把方法最终返回的对象存储起来, 且 @Bean 必须搭配五大类注解之一使用, 且一定要有返回值

  • 先定义一个 User 类
    -
  • 使用 @Bean 存储方法最终返回的 Bean 对象在这里插入图片描述
  • 获取并使用 Bean
    在这里插入图片描述

Bean 的命名规则

  • 使用方法注解存储的 Bean, 默认名称就是 @Bean 注解所加的方法名而不再是类名, (一个类中可能有多个方法需要使用 @Bean, 如果仍然使用类名作为默认命名, 可能多个 Bean 会重名)

  • 也可以给 @Bean 注解传递参数来设定名字, 甚至可以设置一个数组, 其中包含多个名字
    在这里插入图片描述
    获取 Bean 对象时使用这两个名字都可以
    在这里插入图片描述

  • 如果多个 @Bean 注解命名相同, 只有一个 Bean 能被存储
    在这里插入图片描述
    在这里插入图片描述

如果多个 @Bean 使用相同的名称, 例如上述 : 喜羊羊这个 Bean 先被加载, 所以先使用了 user 这个名字, 美羊羊这个 Bean 后被加载, 也想用 user 这个名字, 却被检查到 user 这个名字已经有人用了, 就不存储美羊羊这个 Bean 了

在 @Bean 中重命名之后, 就不能使用默认的命名了


二、获取 Bean

获取 Bean 对象也叫对象装配, 是把对象取出来放到某个类中,有时候也叫对象注⼊

对象注入有三种方式 : 属性注入, Setter 注入, 构造方法注入, 都是使用 @Autowired 注解来实现

按照实际开发的模式, 将 Repository 类注入到 Service 类中, Repository 类的实现如下:

在这里插入图片描述

当前代码以及接下来的代码都会放在dome4这个包下面, 配置文件中也要设置这个包的扫描路径


1, 属性注入

这是开发中最常用的方式, 因为代码简洁方便
在这里插入图片描述
加了 @Autowired 注解 之后, 就会将已经存储过的 UserRepository 这个类型的 Bean 注入进来

通过属性注入的方式, 就可以获取到这个 Bean 并使用它的方法


2, Setter 注入

在这里插入图片描述


3, 构造方法注入

构造方法注入是 Spring 推荐的方式
在这里插入图片描述

构造方法注入更符合单一设计的原则, 因为构造方法只会随着类的加载而调用一次, 不会被任意修改和调用, 也可以保证在使用这个被注入的对象时能被完全初始化, 也可以注入被 final 修饰的变量


4, @Autowired 和 @Resource 的区别

@Autowired 注解也可以被 @Resource 注解代替, 区别如下 :

  • 出身不同:@Autowired 来自于 Spring,而 @Resource 来自于 JDK 的注解;
  • 使⽤时设置的参数不同:相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name 设置,根据名称获取 Bean。
  • @Autowired 可用于 Setter 注入、构造函数注入和属性注入,而 @Resource ,不能⽤于构造函数注入

5, 同一个类型的多个 Bean 注入问题

  • 先定义一个 User 类, 提供 setter 和 toString 方法
    在这里插入图片描述
  • 在 Users 类中使用方法注解存储两个类型为 User 的 Bean, 并设置属性的值在这里插入图片描述
  • 在 Service 层注入 User, 查看 User 的值
    在这里插入图片描述
  • 在 APP 启动类中调用 showUser 这个方法, 观察结果
    在这里插入图片描述

程序执行的结果一定是报错, 因为我们存储了两个类型为 User 的 Bean , 在使用 @Autowired 注入时, 是首先根据 User 这个类型进行匹配, 发现找到了两个 Bean , 于是程序就不能确定到底要注入哪一个了
在这里插入图片描述

@Autowired 注入时, 首先根据类型进行匹配, 如果多个 Bean 类型相同, 再根据 Bean 的名称进行注入

  • 解决方案一 : 存储 Bean 时设置好名称, 注入时再明确指定名称
    在这里插入图片描述在这里插入图片描述
  • 解决方案二 : 使用 @Autowired 搭配 @Qualifier 注解指定注入的 Bean 的名称
    在这里插入图片描述

这个 @Qualifier 注解更像是加了一层筛选操作

  • 解决方案三 : 使用 @Resource 注解指定 name
    在这里插入图片描述
    在这里插入图片描述

使用上述任意三种方式都可以正确的拿到想要的 Bean :
在这里插入图片描述


总结

以上就是本篇的所有内容了:

  • 使用 @Controller、@Service、@Repository、@Component、@Configuration 这五大类注解可以存储 Bean, 在注解中设置一个 Value 参数对 Bean 重命名
  • 使用 @Bean 这个方法注解并搭配任意一个类注解可以将返回值作为 Bean 存储, 在注解中可以指定一个或多个字符串对 Bean 重命名
  • 使用 @Autowired 可以进行属性注入, setter 注入, 构造方法注入, 实现方便的获取 Bean

如果本篇对你有帮助,请点赞收藏支持一下,小手一抖就是对作者莫大的鼓励啦😋😋😋~


上山总比下山辛苦
下篇文章见

在这里插入图片描述

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

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

相关文章

AST入门与实战(一):基于babel库的js反混淆通用模板

AST入门与实战(一):基于babel库的js反混淆通用模板 首发地址:http://zhuoyue360.com/jsnx/106.html 1. 模板代码 通用模板来源自菜老板的知识星球. const fs require(fs); const types require("babel/types"); const parser require("babel/parser")…

【css】css中使用变量var

CSS 变量可以有全局或局部作用域。 全局变量可以在整个文档中进行访问/使用&#xff0c;而局部变量只能在声明它的选择器内部使用。 如需创建具有全局作用域的变量&#xff0c;请在 :root 选择器中声明它。 :root 选择器匹配文档的根元素。 如需创建具有局部作用域的变量&am…

【ARM 调试】如何从 crash 信息找出问题原因

一、问题背景 粉丝在进行 ARM-A 系列软件编程时遇到以下问题&#xff0c;串口打印这段日志后就重启了&#xff0c;粉丝求助问是什么原因&#xff1f; Unhandled Exception in EL3. x30 0x0000000000b99b84 x0 0x00000000179a25b0 x1 …

【笔记】树状数组

【笔记】树状数组 目录 简介引入1. 直接暴力2. 维护前缀和数组总结 定义前置知识&#xff1a; lowbit ⁡ \operatorname{lowbit} lowbit 操作区间的表示方法操作单点修改前缀和查询任意区间查询 例题1: 单点修改&#xff0c;区间查询例题2: 区间修改&#xff0c;单点查询例题3:…

苏州OV泛域名RSA加密算法https

RSA加密算法是一种非对称加密算法&#xff0c;它被广泛应用于信息安全领域。与对称加密算法不同&#xff0c;RSA加密算法使用了两个密钥&#xff0c;一个公钥和一个私钥。公钥可以公开&#xff0c;任何人都可以使用它加密信息&#xff0c;但只有私钥的持有者才能解密信息。RSA加…

探索美颜SDK技术:实现精准人脸美化的算法与挑战

在现代社交媒体和直播平台的兴起中&#xff0c;美颜技术已成为一种不可或缺的元素&#xff0c;让用户能够在镜头前展现出最佳的自己。这种技术的背后有着复杂而精密的算法&#xff0c;由美颜SDK驱动&#xff0c;以实现精准人脸美化。本文将探讨这些算法的核心原理、应用领域以及…

Multimap用法详解

Multimap Multimap 是 Google 的 Guava 库为 Java 引入的一种新集合类型&#xff0c;它允许将多个值存储在单个键下。它被设计为一种替代 Map<K, List> 或 Map<K, Set>&#xff08;JDK 标准集合框架&#xff09;的方案。 Multimap<K, V> 扩展了 AbstractMul…

【金融量化】Python实现根据收益率计算累计收益率并可视化

1 理论 理财产品&#xff08;本金100元&#xff09; 第1天&#xff1a;3% &#xff1a;&#xff08;13%&#xff09; ✖ 100 103 第2天&#xff1a;2% &#xff1a;&#xff08;12%&#xff09;✖ 以上 103 2.06 第3天&#xff1a;5% : &#xff08;15%&#xff09;✖ 以上…

SpringBoot中间件使用之EventBus、Metric、CommandLineRunner

1、EventBus 使用EventBus 事件总线的方式可以实现消息的发布/订阅功能&#xff0c;EventBus是一个轻量级的消息服务组件&#xff0c;适用于Android和Java。 // 1.注册事件通过 EventBus.getDefault().register(); // 2.发布事件 EventBus.getDefault().post(“事件内容”); …

【Linux】带你深入了解多路转接

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录 &#x1f449;多路转接…

竞赛项目 深度学习花卉识别 - python 机器视觉 opencv

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &a…

Maven 生成(打包)带有依赖的可以直接执行的一个 jar 包

在pom中增加如下内容 <build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><archive><manifest><mainClass>com.example.xxx.YourClass</mainClass></manifest></…

Windows和Linux系统上的矢量运算:指令级并行计算SIMD(SSE/AVX)应用细节以及相关跨平台的源码解释

注&#xff1a;本文的SIMD&#xff0c;指的是CPU(base intel x86 architecture)指令架构中的相关概念。不涉及GPU端的算力机制。下面的代码在Win10和Linux上均可用。 基本概念 SSE: Streaming SIMD Extensions, x86 architecture AVX: Advanced Vector Extensions SIMD&#…

Springboot 多数据源 dynamic-datasource动态添加移除数据源

0.前言 上一篇文章我们讲了如何通过多数据源组件&#xff0c;在Spring boot Druid 连接池项目中配置多数据源&#xff0c;并且通过DS注解的方式切换数据源&#xff0c;《Spring Boot 配置多数据源【最简单的方式】》。但是在多租户的业务场景中&#xff0c;我们通常需要手动的…

RabbitMQ 消息队列

文章目录 &#x1f370;有几个原因可以解释为什么要选择 RabbitMQ&#xff1a;&#x1f969;mq之间的对比&#x1f33d;RabbitMQ vs Apache Kafka&#x1f33d;RabbitMQ vs ActiveMQ&#x1f33d;RabbitMQ vs RocketMQ&#x1f33d;RabbitMQ vs Redis &#x1f969;linux docke…

C语言案例 球落地反弹-10

题目&#xff1a;一球从100米高度自由落下&#xff0c;每次落地后反跳回原高度的一半;再落下&#xff0c;求它在第10次落地时&#xff0c;共经过多少米第10次反弹多高&#xff1f; 程序分析 球在落地后会反弹为原高度的一半&#xff0c;若设高度为h&#xff0c;那么每次落地的…

MATLAB程序初始化OpenFOAM颗粒位置

问题引入 在OpenFOAM的颗粒两相流求解器中&#xff0c;我们可以采用manualInjection的方式进行自定义颗粒的初始位置&#xff0c;这个命令十分方便&#xff0c;在CFDEM中也有类似的命令&#xff0c;不过CFDEM中的命令更加强大&#xff0c;我们不仅可以定义颗粒的初始位置&…

【我的2023秋招记录】溯流

我的2023秋招记录 开篇&#xff08;2023-08-11&#xff09; 2023已经过去大半年了&#xff0c;久违地打开CSDN&#xff0c;发现上一篇博客还停留在2022年的10月。那时候正值疫情严重&#xff0c;研究所回不去&#xff0c;整天呆在家里面摆烂摸鱼&#xff0c;也时常忧虑之后的…

pikachu中RCE出现乱码的解决的方案

exec “ping” 输入127.0.0.1 这种乱码的解决办法就是在pikachu/vul/rce/rce_ping.php目录里面的第18行代码 header("Content-type:text/html; charsetgbk");的注释打开即可。 BUT但是吧&#xff01;又出现了其他的乱码&#xff01;但是搞完这个再把它给注释掉就行了…

mac ssh连接另一台window虚拟机vm

vmware配置端口映射 编辑(E) > 虚拟网络编辑器(N)... > NAT设置(S)... window防火墙&#xff0c;入站规则添加5555端口 控制面板 > 系统和安全 > Windows 防火墙>高级设置>入站规则>新建规则... tips windows查看端口命令&#xff1a;netstat -ano | f…