Spring使用注解存储和读取对象

在这里插入图片描述

文章目录

  • 一、存储Bean对象
    • 配置扫描
    • 添加注解存储Bean对象
    • 注解使用范围
    • Bean的命名
    • 五大类注解的关系
    • 为什么需要五大类注解?
  • 二、方法注解@Bean
    • Bean重命名
  • 三、对象注入
    • 属性注入
    • Setter注入
    • 构造方法注入
    • @Autowired 和 @Resource 的区别

一、存储Bean对象

在这里插入图片描述
之前我们存储Bean时,需要在spring-config.xml中添加bean注册才行,这样的方式并不简单。我们要想更简单的存储和读取对象的核心是使用注解

1.使用类注解(五大类注解):
@Controller:控制器,验证用户请求的数据正确性(安保系统)
@Service:服务层,编排和调度具体执行方法的(客服中心)
@Repository:持久层,和数据库进行交互,等同于DAO(Data Access Object) 数据访问层
@Component:组件(工具类)
@Configuration:配置项(配置项目中的一些配置)

2.方法注解:
@Bean路径

配置扫描

要想将对象成功存储到Spring中,物品们需要配置一下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到Spring中,需要在spring-config.xnl添加如下配置:

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

在这里插入图片描述
这步是十分重要的,要是不是在配置扫描包下的类对象,即使加了注解,也是不能存储到Spring中的

添加注解存储Bean对象

使用 @Controller 存储 bean 的代码如下所示:

@Controller //将对象存储到Spring中
public class StudentController {
    public void hello() {
        System.out.println("hello Im student");
    }
}

读取StudentController对象

public static void main(String[] args) {
        //得到Spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean
        StudentController studentController =
                context.getBean("studentController",StudentController.class);
        //调用bean方法
        studentController.hello();
    }

在这里插入图片描述
使用 @Service 存储 bean 的代码如下所示:

@Service
public class StudentService {
    public void hello() {
        System.out.println("hello Im studentService");
    }
}

获取Bean对象:

public static void main(String[] args) {
        //得到Spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //得到bean
        StudentService studentService =
                context.getBean("studentService",StudentService.class);
        //调用bean方法
        studentService.hello();
    }

在这里插入图片描述
其他几个类注解的使用方法都是一致的,在这里就不一一演示了

注解使用范围

1.是否可以与component-scan一起使用?
在这里插入图片描述
在这里插入图片描述
我们可以发现是可以一起使用的

2.五大类注解可以不再component-scan包下吗?
不可以

3.component-scan下的类,没有加五大类注解,可以存储到Spring吗?
不可以

4.componemt-scan下的所有子包下的类只要加了五大类注解,可以存储到Spring吗?
子包下的类只要加了五大类注解,同样可以存储到Spring中

Bean的命名

在这里插入图片描述
我们在获取Bean对象时,传入名称时,一般分为两种情况:
默认情况下:使用原类名首字母小写就能读取到Bean对象
特殊情况:原类名如果首字母和第二个字母都是大写的情况,那么使用原类名获取
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

五大类注解的关系

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
可以认为@Controller / @Service / @Repository /@Configuration都是@Component的"子类",都是针对于@Component的一个扩展

为什么需要五大类注解?

我们可以发现,只要我们在类上加了注解,都可以获取到Bean对象,为什么需要这么多的类注解呢?
为了让程序员看到注解之后一眼就知道当前类的作用

JavaEE标准分层:
1.控制层(Controller)
2.服务层(Service)
3.数据持久层(Dao)
在这里插入图片描述

二、方法注解@Bean

五大类注解是添加到某个类上的,而方法注解是放到方法上的

在这里插入图片描述
我们首先准备一个实体类,然后使用方法注解@Bean将对象存储到Spring容器中

public class UserBeans {
    @Bean
    public static User getUser() {
        User user = new User();
        user.setUid(1);
        user.setUsername("张三");
        user.setPassword("123456");
        return user;
    }
}

然后从Spring容器中获取对象

public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml");
        User user = context.getBean("user",User.class);
        System.out.println(user);
    }

在这里插入图片描述
我们发现使用的时候报错了,没有名为user的Bean对象,出现这种现象一共有两大原因:

1.@Bean命名规则与五大类注解的命名规则不同,@Bean命名规则,默认@Bean存储的对象名称 == 方法名

在这里插入图片描述
2.@Bean注解必须要搭配五大类注解一起使用(Spring为了提升性能所做的规定)
在这里插入图片描述
在这里插入图片描述
现在就可以正常获取到Bean对象了

Bean重命名

我们上述通过方法名获取Bean对象太抽象了,我们可以通过设置name属性给Bean对象进行重命名操作,如下述操作:
在这里插入图片描述
我们给Bean起一个user的名字

在这里插入图片描述
我们可以发现就可以通过这个重名获取了。
我们这里的重命名可以起多个名字,因为我们Spring容器中允许将同一类型的对象,存储到容器多份

在这里插入图片描述
当@Bean使用了重命名之后,使用方法名是否还能获取到对象?
不能,当@Bean对象重命名之后,默认的使用方法名获取的方式就不能使用了
在这里插入图片描述

三、对象注入

获取Bean对象也称之为对象装配,就是将对象取出来放到某个类中,有时候也称之对象注入
对象注入的实现方法有以下三种:
1.属性注入
2.Setter注入
3.构造方法注入

属性注入

属性注入是使用@AutoWired注解实现的

@Component
public class Group {
    @Autowired
    private User user;

    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}

在这里插入图片描述
这样就可以实现属性注入了,虽然属性注入实现简单、使用简单,但它有以下缺点:
在这里插入图片描述
我么将鼠标放在注解上,会提示我们属性注入不推荐使用

1.无法注入一个不可变对象(final 修饰的对象)
在这里插入图片描述
final修饰的对象要么直接复制,要么在构造方法中赋值。放我们属性注入时,上述两种都不满足,所以就注入失败了
2.通用性,属性注入只能在IoC容器中使用,其他容器中不支持
3.违背单一设计原则。简单理解就是注入方式越简单,滥用的概率越大,出现违背单一职责的概率也越大

Setter注入

setter注入也是使用@Autowired注解实现

@Component
public class Group {
    
    private  User user;
    @Autowired
    public void setUser(User user) {
        this.user = user;
    }
    public User getUser() {
        return user;
    }
    
}

在这里插入图片描述
我们使用Setter注入也可以成功存储取出,Setter注入符合单一职责的设计原理,但也有以下缺点:
1.不能注入不可变对象
在这里插入图片描述
2.注入的对象可能被修改,因为我们在任何事件都可以调用setXXX方法来改变注入的对象

构造方法注入

构造方法注入也是Spring官方推荐的注入方式:

public class Group {

    private User user;

    @Autowired
    public Group(User user) {
        this.user = user;
    }
}    

在这里插入图片描述
如果当前类只有一个构造方法的话,@Autowired注解可以省略
在这里插入图片描述
在这里插入图片描述
构造方法注入。有以下优点:
1.可注入不可变对象
在这里插入图片描述
2.注入对象不会被修改
构造方法在对象创建时只会执行一次,因为不存在注入对象被随时修改的情况
3.完全初始化
构造方法是在对象创建之前之前的,当我们使用被注入的对象时,会被完全初始化
4.通用性强
支持各种框架

@Autowired 和 @Resource 的区别

在进行类注入时,除了可以使用@Autowired关键字,我们还可以使用@Resource进行注入
在这里插入图片描述
在这里插入图片描述
@Autowired 和 @Resource 的区别:
1.出身不同:@Autowired是Spring的注解,@Resource是JDK的注解
2.查找顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询
3.支持参数不同,@Autowired支持一个,@Resource支持7个
在这里插入图片描述
在这里插入图片描述
4.依赖注入支持不同:@Autowired支持三种注入,而@Resource只支持属性注入和Setter注入

当同一类型多个Bean时会报错
在这里插入图片描述
在这里插入图片描述
再去获取对象就会出错,非唯一的Bean的对象,因为我们Spring中有user1和user2,不知道注入那个,解决方案有两个:
1.使用@Resource(name = “XXX”)
在这里插入图片描述
在这里插入图片描述
2.使用@Qualifier注解定义名称,搭配@Autowired注解使用
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5 Redis缓存穿透、击穿、雪崩、分布式锁、布隆过滤器

1 Redis 应用问题解决 1.1 缓存穿透 1.1.1 问题描述 key 对应的数据在数据源并不存在&#xff0c;每次针对此 key 的请求从缓存获取不到&#xff0c;请求都会压到数据源&#xff08;数据库&#xff09;&#xff0c;从而可能压垮数据源。比如 用一个不存在的用户 id 获取用户…

一份标准的软件测试方案模板

第一章 概述 ​ 软件的错误是不可避免的&#xff0c;所以必须经过严格的测试。通过对本软件的测试&#xff0c;尽可能的发现软件中的错误&#xff0c;借以减少系统内部各模块的逻辑&#xff0c;功能上的缺陷和错误&#xff0c;保证每个单元能正确地实现其预期的功能。检测和排…

亚马逊云科技开启您的云财务管理之旅:云财务运营

亚马逊云科技“开启您的云财务管理之旅”系列内容提出了关于如何启动和实施一个成功的云财务管理CFM战略的建议。云财务管理CFM的三个原则&#xff1a;SEE-查看、SAVE-节省和PLAN-计划。接下来介绍的是第四个阶段&#xff1a;RUN-运营。 在这一阶段&#xff0c;可以了解云财务管…

vue 做一个文本展示 点击文本弹出element ui的时间选择器 但不会出现element ui时间组件的那个输入框

我们先来创建一个vue2项目 引入element ui 然后 找到一个组件 这样写 <template><div><el-date-pickerv-model"value"type"datetimerange"align"right"unlink-panelsrange-separator"至"start-placeholder"开始日…

C/C++的命名空间和调用函数的详细讲解

目录 空函数 调用函数 调用 执行流程 命名空间 在创建函数时&#xff0c;必须编写其定义。所有函数定义包括以下组成部分&#xff1a; 名称&#xff1a;每个函数都必须有一个名称。通常&#xff0c;适用于变量名称的规则同样也适用于函数名称。形参列表&#xff1a;调用函…

手机摄影笔记(二)

第5章 镜头语言 镜头语言分类&#xff08;8个&#xff09;&#xff1a; 推&#xff1a;从远到近 拉&#xff1a;从近到远 摇&#xff1a;机位固定&#xff0c;旋转手机拍全景或者跟着拍摄对象进行摇摄&#xff08;跟摇&#xff09;.通常用此方式来介绍环境时&#xff0c;表现的…

开放原子训练营(第三季)inBuilder低代码开发实验室---报销单录入系统

作为一名低代码初学者&#xff0c;我使用inBuilder系统设计了一款报销单录入系统&#xff0c;实现了报销单录入与显示报销单列表的功能&#xff08;如图1与图2所示&#xff09;&#xff0c;并获得了很多开发心得。从inBuilder系统的优点、缺点以及开发过程三方面出发&#xff0…

基于SpringBoot,vue的家政服务平台的设计与实现

背景 以往的家政服务管理平台的管理&#xff0c;一般都是纸质文件来管理家政服务信息&#xff0c;传统的管理方式已经无法满足现代人们的需求&#xff1b;使用家政服务管理平台, 首先可以大幅提高家政服务信息检索&#xff0c;只需输入家政服务相关信息就能在数秒内反馈想要的…

JavaScript学习(一)

一、JavaScript的背景及知识结构 1、三个问题 什么是JavaScript&#xff1f;JavaScript能干什么&#xff1f;JavaScript是由什么构成的&#xff1f;怎样学习JavaScript&#xff1f; 2、什么是JavaScript&#xff1f; ①JavaScript是一种轻量级的编程语言&#xff1b;借鉴了J…

【SSA-LSTM】基于麻雀算法优化LSTM 模型预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

C#_Struct与Class的差异

简述 struct属于值类型&#xff0c;class属于引用类型 存储地址 struct储存于栈&#xff0c;class储存于堆&#xff08;class于栈中储存引用&#xff09; 传参性质 struct属于值传递&#xff0c;在函数内对参数进行修改&#xff0c;不会修改struct class处于引用传递&…

行为型模式-状态模式

状态模式 概述 【例】通过按钮来控制一个电梯的状态&#xff0c;一个电梯有开门状态&#xff0c;关门状态&#xff0c;停止状态&#xff0c;运行状态。每一种状态改变&#xff0c;都有可能要根据其他状态来更新处理。例如&#xff0c;如果电梯门现在处于运行时状态&#xff0…

MySQL

关系型数据库 数据结构&#xff1a;二维表格 库 -> 表 -> 列&#xff08;字段&#xff09;&#xff1a;用来描述对象的一个属性 -> 行&#xff08;记录&#xff09;&#xff1a;用来描述一个对象的信息 市面上&#xff1a;MySQL 、Mariadb 、PostgreSQL 、 Oracle&a…

汽车电路图、原理框图、线束图、元器件布置图的识读技巧与要点

摘要&#xff1a; 想要读懂汽车电路图就必须把电的通路理清楚&#xff0c;即某条线是什么信号&#xff0c;该信号是输入信号、输出信号还是控制信号以及信号起什么作用&#xff0c;在什么条件下有信号&#xff0c;从哪里来&#xff0c;到哪里去。 一、汽车电路图的识读技巧 1.…

在 Python 中将 Tqdm 与 Asyncio 结合使用

动动发财的小手&#xff0c;点个赞吧&#xff01; 简介 困扰 在 Python 中使用并发编程来提高效率对于数据科学家来说并不罕见。在后台观察各种子进程或并发线程以保持我的计算或 IO 绑定任务的顺序总是令人满意的。 但是还有一点困扰我的是&#xff0c;当我在后台并发处理成百…

PBDB Data Service:Thumbnail images of lifeforms(生命形式的缩略图)

Thumbnail images of lifeforms&#xff08;生命形式的缩略图&#xff09; 描述用法参数方法响应值格式术语表 描述 此操作返回表示指定分类的图像&#xff0c;或关于图像的信息。如果后缀是 .png&#xff0c;则返回图像内容数据。否则&#xff0c;将以指定的格式返回一个描述…

9:00进去,9:05就出来了,这问的也太···

从外包出来&#xff0c;没想到死在另一家厂子了。 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内推…

【Halcon】新建程序 读取图片 路径设置

文章目录 1 新建程序2 读取一张图片3 图片路径4 图片格式读取报错5 快速添加 绝对路径1 新建程序 点击新程序图标,即可新建; 程序另存为,会弹出保存路径 2 读取一张图片 read_image(Image,fabrik)

软件测试工程师的核心竞争力究竟是什么?

对于测试员而言&#xff0c;了解自己岗位的核心竞争力是非常重要的。在职业初期&#xff0c;许多人认为掌握代码才是软件测试的核心竞争力&#xff0c;但是随着经验的增加&#xff0c;我们会发现真正的核心竞争力是由多个方面组成的。 首先&#xff0c;测试人员需要具备良好的测…

Windows环境安装Elasticsearch和Kibana

文章目录 1 Elasticsearch1.1 下载1.2 解压并添加环境变量1.3 访问1.4 cmd命令1.5 中文分词器1.5.1 下载1.5.2 安装1.5.2.1 命令安装1.5.2.2 手动安装1.5.2.3 验证分词 1.6 使用curl批量导入 2 安装 kibana2.1 下载kibana2.2 中文界面2.3 操作索引2.3.1 增加索引2.3.1.1 单条新…
最新文章