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

news2024/12/28 20:30:12

文章目录

  • 前言
  • 一、存储 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.coloradmin.cn/o/861311.html

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

相关文章

机器学习、深度学习项目开发业务数据场景梳理汇总记录三

本文的主要作用是对历史项目开发过程中接触到的业务数据进行整体的汇总梳理&#xff0c;文章会随着项目的开发推进不断更新。 这里是续文&#xff0c;因为CSDN单篇文章内容太大的话就会崩溃的&#xff0c;别问我怎么知道的&#xff0c;问就是血泪教训&#xff0c;辛辛苦苦写了一…

C语言 指针与const

const 修饰变量&#xff0c;使得这个变量不能被修改。 const 对指针具有两种修饰的方式&#xff0c;且两种方式所限制的情况不同。 当const在 * 的左边 const int * p &n; 或者 int const * p &n; 当const在*的左边时&#xff0c;指针变量p所指向的空间内容无法被修…

C语言 指针与assert

assert 又称断言&#xff0c;需要包含头文件 assert.h 用于在运行时确保程序符合指定条件&#xff0c;如果不符合&#xff0c;就报错终止运行。 assert(p ! NULL); 上面代码在程序运行到这一行语句时&#xff0c;验证变量 p 是否等于 NULL。如果确实不等于 NULL &#xff0c;…

慎写指针类型的全局变量

简述: 在 关于range二三事[1] 第二个case中,介绍了对于指针类型的 切片/map变量A 的循环,要格外注意, 迭代出的value作用域是整个方法而非循环体内. 改进办法:在循环体中引入中间变量,"暂存"下每次迭代的value的值 但对于这个A,如果是全局变量,则又极有可能出现问题:…

Apache Maven简介安装及系统坏境配置eclipse配置Apache Maven---详细介绍

一&#xff0c;简介 Maven可以简化项目的构建和依赖管理&#xff0c;并提供了一种规范化和可复用的方式来管理Java项目。它广泛应用于Java开发领域&#xff0c;简单来说&#xff1a;它提供了一个简单而强大的方式来管理项目的构建、依赖关系和文档在企业级项目中被广泛采用。 1…

京东秋招攻略,备考在线测评和网申笔试

京东秋招简介 伴随着社会竞争越来越激烈&#xff0c;人们投递简历的岗位也变得越来越多元&#xff0c;而无论人们的选择面变成何样&#xff0c;那些知名度较高的企业&#xff0c;永远都备受关注&#xff0c;只要其一发布招聘公告&#xff0c;总有人第一时间踊跃报名。而作为这…

Java算法_ LRU 缓存(LeetCode_Hot100)

题目描述&#xff1a;请你设计并实现一个满足 LRU &#xff08;最近最少使用&#xff09; 缓存 约束的数据结构。 获得更多&#xff1f;算法思路:代码文档&#xff0c;算法解析的私得。 运行效果 完整代码 import java.util.HashMap; import java.util.Map;/*** 2 * Author: L…

winform中嵌入cefsharp, 并使用selenium控制

正常说&#xff0c; 需要安装的包 下面是所有的包 全部代码 using OpenQA.Selenium.Chrome; using OpenQA.Selenium; using System; using System.Windows.Forms; using CefSharp.WinForms; using CefSharp;namespace WindowsFormsApp2 {public partial class Form1 : Form{//…

(kubernetes)k8s常用资源管理

目录 k8s常用资源管理 1、创建一个pod 1&#xff09;创建yuml文件 2&#xff09;创建容器 3&#xff09;查看所有pod创建运行状态 4&#xff09;查看指定pod资源 5&#xff09;查看pod运行的详细信息 6&#xff09;验证运行的pod 2、pod管理 1&#xff09;删除pod 2…

搜索二叉树(二叉树进阶)

目录 1.二叉搜索树 1.1二叉搜索树概念 1.2二叉搜索树操作 2.3二叉搜索树的实现 2.4二叉搜索树的应用 2.5二叉搜索树的性能分析 1.二叉搜索树 1.1二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者是具有以下性质的二叉树&#xff…

mac安装nvm管理工具遇到的问题和解决方法

nvm 是一款可以管理多版本node的工具&#xff0c;因为是刚买没多久的电脑之前用的都是windows&#xff0c;昨天折腾了一下午终于倒腾好了 第一步&#xff1a; 卸载电脑已有的node&#xff1b;访问nvm脚本网址&#xff0c;另存为到电脑上任何目录&#xff0c;我是放在桌面上的…

OSPF技术入门(第三十四课)

1 OSPF的介绍 OSPF是一种链路状态路由协议,主要用于IP网络中的路由选择。它是一种开放协议,能够在不同的网络设备之间进行通信。OSPF利用链路状态数据库来描述网络拓扑结构,并通过Dijkstra算法计算出最短路径。它支持按照精确度划分的路由优先级,以及多个相等的路径,并能自…

微服务分布式搜索引擎 ElasticSearch 查询文档

文章目录 ⛄引言一、DSL查询文档⛅DSL 查询分类 二、DSL查询实例⛅全文检索查询⏰精确查询⚡地理坐标查询⌚复合查询 ⛵小结 ⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海…

服务器数据恢复-断电导致ext4文件系统文件丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器挂载一台存储设备&#xff0c;存储中划分一个Lun&#xff1b;服务器操作系统是Linux centos&#xff0c;EXT4文件系统。 服务器故障&分析&#xff1a; 意外断电导致服务器操作系统无法启动&#xff0c;系统在修复后可以正常启动&…

竞赛项目 深度学习的动物识别

文章目录 0 前言1 背景2 算法原理2.1 动物识别方法概况2.2 常用的网络模型2.2.1 B-CNN2.2.2 SSD 3 SSD动物目标检测流程4 实现效果5 部分相关代码5.1 数据预处理5.2 构建卷积神经网络5.3 tensorflow计算图可视化5.4 网络模型训练5.5 对猫狗图像进行2分类 6 最后 0 前言 &#…

在Ubuntu中使用Docker启动MySQL8的天坑

写在前面 简介&#xff1a; lower_case_table_names 是mysql设置大小写是否敏感的一个参数。 1.参数说明&#xff1a; lower_case_table_names0 表名存储为给定的大小和比较是区分大小写的 lower_case_table_names 1 表名存储在磁盘是小写的&#xff0c;但是比较的时候是不区…

CMAKE生成exe文件时运行时有cmd窗口

1、运行exe执行文件 会有cmd弹窗 2、解决方法 只需要在cmakelists.txt中添加set(CMAKE_CXX_FLAGS “-mwindows”) 或者在cmake时指定编译参数cmake -DCMAKE_CXX_FLAGS"-mwindows"即可 如果用的是c而不是c&#xff0c;就只需把CXX改为C 重新编译打包运行后没有cmd弹…

centos自动同步北京时间

1、安装ntpdate服务 yum -y install ntpdate 2、加入自动任务计划 查找ntpdate的路径&#xff1a; which ntpdate 复制这个路径。 编辑自动任务计划并加入ntpdate&#xff1a; crontab -e # 每小时第30分钟同步AD域控时间 30 * * * * /usr/sbin/ntpdate -u 192.168.2.8 > …

超低成本FPGA JTAG方案

今天给大家带来一款超低成本的FPGA JTAG方案&#xff0c;硬件核心是用树莓派Pico&#xff0c;使用相关芯片自己制作JTAG则非常便宜&#xff0c;RP2040某宝的报价只有4元&#xff0c;所以自己制作成本非常低廉&#xff0c;当然使用Pico成本也不是很高&#xff0c;所以今天就以Pi…

ChineseChess

外卖中国象棋的梗。 外卖免单题&#xff1a; 如图&#xff0c;红棋先行&#xff0c;至少几步绝杀黑房&#xff08;黑房尽量不让自己输&#xff09;&#xff1f; ChineseChess.java 【帅】是左出还是右出&#xff0c;取决于&#xff0c;上图黑方那边的【士】 如图&#xff0c…