Spring(二):更简单的存储与读取 Bean

news/2025/2/12 18:15:11/

通过上一章的Spring,我们基本实现了Spring 的读取与存储,但是在操作过程中,读取与存储并没有那么得“简单” 一套流程还是很复杂,所以,本章来介绍更加简单得读取与存储。

在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,也就是我们接下来要学习 Spring 中的相关注解,来存储和读取 Bean。

更简单的存

之前我们存储 Bean 时,需要在 spring-config 中添加⼀⾏ bean 注册内容才⾏:

 我们现在可以通过写一行注解就代替一行 配置。

配置扫描路径

如果这缺少了这个前置工作,那么整个项目的操作都操作不起来。

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

这个扫描路径就是去扫描 该路径底下是否加了 “五大” 注解,一经发现注解,就给他添加到 Spring(容器) 中。

如果不是在该扫描路径底下,即使是加了扫描路径,也不会加入到Spring 中。

所以,这个配置的扫描路径需要格外注意,不能太大,太大就会导致项目启动的很慢,太小又会导致添加不到。

添加注解存储 Bean 对象

想要将对象存储在 Spring 中,有两种注解类型可以实现:
  1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration。
  2. ⽅法注解:@Bean。

举个栗子:

通过这个 注解就可以 将对象存储到 Spring 中

当然,存储的前提是 路径配置正确。

其他的四个注解也一样,这里就不一一举例了。

看看结果:

 这里首字母小写不完全正确,到获取的 部分再来讲解。

为什么要这么多类注解?

就是让程序员看到类注解之后,就能直接了解当前类
的⽤途,⽐如:
  • @Controller:表示的是业务逻辑层;
  • @Servie:服务层;
  • @Repository:持久层;
  • @Configuration:配置层
程序的⼯程分层,调⽤流程如下:

类注解之间的关系  

 我们通过查看源码可以知道:

查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现:
其实这些注解⾥⾯都有⼀个注解 @Component,说明它们本身就是属于 @Component 的“⼦类”。

Bean注解

除了五大类注解,还可以通过 Bean 注解(这个Bean 注解不是类注解,而是方法注解):
我来看看单单只有一个 Bean 注解是无法注入进 容器中 ,
Bean 在使用的前提是必须配合五大类注解,才可以生效

更简单的取

这个取,主要就是针对这个 Bean 来取

上述过程中,这个通过默认名去取的会产生问题,

现在这个方法名叫做 UUUU 我们再来使用刚刚首字母小写的方式,看看能不能拿到:

我们发现它找不到这个 对象了。为啥呢?

我们来看看Bean生成名称的源码:

我们可以发现,如果是首字母和第二个字母都大写的话 需要直接返回它的原名。

当然,我们在Bean 注解之后还可以加上名字:

获取 Bean 对象

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

对象装配(对象注⼊)的实现⽅法以下 3 种:
  1.  属性注⼊
  2.  构造⽅法注⼊
  3.  Setter 注⼊
接下来,我们分别来看

属性注入

举个例子

在Users 类中添加了 user1 的方法,返回值是User。

 

最终是可以获取到User对象。

 解释:这里将 Users 这个类注入到了 Spring 容器中,并且还将 user1 这个方法注入到了容器中,它返回的对象 是 User 这个类。 所以可以在后续拿到 User 对象。怎么拿的,就是通过 Autowrid 这个注解(这就是属性注入)。

假设,我们给他再次注入一个 User 对象至容器中,看看还能不能再次属性注入成功

 反而还报错,容器中注入了 两个 返回对象为 User 的,它并不知道你具体需要哪个。

我们大致可以推测 Spring 容器存储Bean 对象的逻辑:

@Bean 对象注意事项 

如果多个Bean 对象使用相同的名称,那么程序就会报错,但是第一个 Bean 对象之后的对象不会被放到容器中,也就是只有在第一次创建Bean 对象的时候,会将对称和 Bean 名称关联起来,后续在有相同的名称的 Bean 存储的时候,容器会自动忽略。

那么要如何来拿到呢?

我们有如下几种方法:

方法一:在容器中存储不以默认的名字为主,给他手动添加一个 名字,此后就用手动添加的名字

 方法二:使用 Qualifier 这个注解,指定 需要找的User 对象

属性注入的特点:

优点:

  1. 使用简单,直接就可以通过 Autowried 注入

缺点:

  1. 无法注入 final 修饰的类,final 的特征:要么直接复制,要么在构造方法中赋值
  2. 通用性问题:只能适用于 IoC容器,如果是非 IoC 容器,只有在使用时才会报 空指针异常。
  3. 更容易违背单一设计原则,因为使用起来比较方便

Setter 注入

Setter 注入不过就是将 之前的属性改成了一个 set 方法:

Setter注入的特点:

 优点:

  1. 通常 Setter 只 Set 一个属性,所以 Setter 注入 更加符合单一设计原则

缺点:

  1. Setter 注入 的对象可以被修改,setter 本来就是一个方法,既然时一个方法,那么就可能被多次调用和修改

构造方法注入

构造方法注入是 Spring 4.0 之后推荐的注入方法

 构造方法注入的特点:

优点:

  1. 可以注入一个final 修饰的变量
  2. 注入的对象不会被修改,因为 构造方法只加载一次
  3. 构造方法注入可以保证诸如对象完全初始化
  4. 构造方法注入通用性更好

缺点

  1. 写法比属性注入复杂
  2. 使用构造方法注入无法解决循环依赖的问题(这里涉及到 Spring 三级缓存,以后再说)

@Resource 另一种关键字

除了 @Autowired 还有一个 注解

 我们可以看到它来自于 Java 拓展类

并且它不能作用在构造方法上:

@Autowired 和 @Resource 的区别

  1. 出身不同:@Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解;
  2. 使⽤时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如name 设置,根据名称获取 Bean。
  3. @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注⼊和属性注⼊,不能⽤于构造函数注⼊

总结

1. 将对象存储到 Spring 中:

  • a. 使⽤类注解:@Controller、@Service、@Repository、@Configuration、@Component【它们之间的关系】
  • b. 使⽤⽅法注解:@Bean【注意事项:必须配合类注解⼀起使⽤】

2. Bean 的命名规则:

  • ⾸字⺟和第⼆个字⺟都⾮⼤写,⾸字⺟⼩写来获取 Bean,如果⾸字⺟和第⼆个字⺟都是⼤写,那么直接使⽤原 Bean 名来获取 Bean。

3. 从 Spring 中获取对象:

  • a. 属性注⼊
  • b. Setter 注⼊
  • c. 构造函数注⼊(推荐)

4. 注⼊的关键字有:

  • a. @Autowired
  • b. @Resource

5. @Autowired 和 @Resource 区别:

出身不同; 使⽤时设置参数不同 @Resource ⽀持更多的参数,⽐如 name
 


http://www.ppmy.cn/news/979800.html

相关文章

【Shell】Shell编程之免交互

免交互&#xff1a;不需要人为控制就可以完成的自动化操作 自动化运维 Shell脚本和免交互是一个概念&#xff0c;但是两种写法 here document 使用i/o重定向的方式将命令的列表提供给交互式的程序或者命令 是一种标准输入&#xff0c;只能接受正确的指令或命令&#x…

关于a^b%mod

当b非常大时&#xff0c;我们不能够直接对b取模&#xff0c;即a^(b%mod)!a^b%mod&#xff0c;可以利用欧拉定理 参考博客&#xff1a;HDU-4549(矩阵快速幂欧拉定理)_薄层的博客-CSDN博客

测试覆盖率 JVM 字节码测试运用 - 远程调试、测试覆盖、影子数据库

目录 前言&#xff1a; 简介 基础使用方式介绍 工具特性 前言&#xff1a; 在软件开发中&#xff0c;测试覆盖率是一个非常重要的指标&#xff0c;它表示代码中所有的测试用例是否都已经被覆盖到。JVM 字节码测试是一种比较新的测试方法&#xff0c;它可以对 JVM 字节码进…

借助 Mybatis 的动态 SQL 解决传参不确定问题

在上一篇的&#xff1a;Mybatis 操作数据库的基本 CRUD 以及查询操作详析_糊糊涂涂的博客-CSDN博客中介绍了Mybatis使用固定SQL语句操作数据&#xff0c;本篇介绍 Mybatis 一个强大的特性&#xff1a;动态SQL。 动态 SQL 解决什么问题&#xff1f; 那当我们要执行的业务逻辑有…

(css)列表点击前后样式

(css)列表点击前后样式 效果&#xff1a; html <ul v-show"rightOne" class"one-content"><liv-for"(item,index) in exampleList":key"index"click"searchHandle(item,index)"class"liClass":class&qu…

Minimum Snap闭式求解相关公式推导

文章目录 1 M i n i m u m Minimum Minimum S n a p Snap Snap闭式求解的推导1.1 二次规划等式约束构建1.2 求 d d d1.3 转成无约束优化问题 1 M i n i m u m Minimum Minimum S n a p Snap Snap闭式求解的推导 可以看看我的这几篇Blog1&#xff0c;Blog2&#xff0c;Blog…

odoo16中的 ‘ir.ui.view‘ object has no attribute ‘_render‘

odoo16中的 ir.ui.view object has no attribute _render 查了下odoo15的代码: def _render(self, values=None, engine=ir.qweb, minimal_qcontext=False):""" Render the template. If website is enabled on request, then extend rendering context with …

uniapp实现预约时间选择弹窗组件

做了个组件&#xff0c;实现出当日预约时间组件&#xff0c;效果图如下 废话不多说&#xff0c;直接上代码&#xff0c;代码简单&#xff0c;参数自己任意改 <template><view class"inventory"><u-popup :show"show" :round"10"…