【Java】Spring更简单的读取和存储

news2024/10/6 18:35:14

文章目录

  • Spring更简单的读取和存储对象
    • 1. 存储Bean对象
      • 1.1 前置工作:配置扫描路径
      • 1.2 添加注解存储Bean对象
        • 1.2.1 @Controller(控制器存储)
        • 1.2.2 @Service(服务存储)
        • 1.2.3 @Repository(仓库存储)
        • 1.2.4 @Component(组件存储)
        • 1.2.5 @Configuration
      • 1.3 为什么要这么多类注解
        • 1.3.1 类注解之间的关系
        • 1.3.2 Bean命名规则
      • 1.4 方法注解
        • 1.4.1 方法注解要配合类注解来使用
        • 1.4.2 重命名Bean
    • 2. 获取Bean对象(对象装配)
      • 2.1 属性注入
      • 2.2 构造方法注入
      • 2.3 Setter注入
      • 2.4 三种注入的优缺点
      • 2.5 @Resource:另一种注入关键字
      • 2.6 同一个类型多个@Bean报错
    • 3. 总结

Spring更简单的读取和存储对象

我们现在已经可以实现基本的Spring读取和存储对象的操作了,但在操作过程当中。我们发现并没有那么简单。在Spring当中想要更简单的存储和使用对象的核心是使用注解接下了就了解下,如何使用注解来存储和获取Bean

1. 存储Bean对象

之前存储Bean对象,需要添加一行bean才能注册,如下图所示:

在这里插入图片描述

而现在只需要一个注解,就可以代替一行的配置,但是我们先要来点准备工作

1.1 前置工作:配置扫描路径

注意:想要把Bean成功的存储到Spring当中,我们需要配置一下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确识别并保存到Spring当中

spring-config.xml当中添加如下配置:

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

在这里插入图片描述

圈起来的是扫描路径,表示所有要存放到Spring中的Bean的根目录

1.2 添加注解存储Bean对象

想要将对象存储到Spring当中,有两种注解类型可以实现:

  1. 类注解:@Controller @Service @Repository @Component @Configuration
  2. 方法注解:@Bean

接下来,分别来看:

1.2.1 @Controller(控制器存储)

@Controller
public class UserController {
    public void sayHi() {
        System.out.println("你好Controller");
    }
}

这时我们按照之前的方法获取到Spring中的Bean

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
UserController userController = context.getBean("userController", UserController.class);
userController.sayHi();

1.2.2 @Service(服务存储)

@Service
public class UserService {
    public void sayHi() {
        System.out.println("你好Service");
    }
}

1.2.3 @Repository(仓库存储)

@Repository
public class UserRepository {
    public void sayHi() {
        System.out.println("你好Repository");
    }
}

1.2.4 @Component(组件存储)

@Component
public class UserComponent {
    public void sayHi() {
        System.out.println("你好Component");
    }
}

1.2.5 @Configuration

@Configuration
public class UserConfiguration {
    public void sayHi() {
        System.out.println("你好Configuration");
    }
}

1.3 为什么要这么多类注解

既然功能都是一样的,为什么需要这么多呢?

这和为什么每个省/市都有自己的车牌号是一样的?比如陕西车牌号就是:陕XXXXXX,北京车牌号是:京XXXXXXXX。甚至一个省不同的县区车牌号都是不一样的。这样做的好处就是节约了号码,更重要的是可以直观的标识一辆车的归属地

那么为什么需要这么多类的注解也是相同的原因,就是让程序员看到类注解之后,就直接了解当前类的用途。

让代码的可读性提高,让程序员能够直观的判断当前类的用途

比如:

  • @Controller表示业务逻辑层
  • @Service表示服务层
  • @Repository表示持久层
  • @Configuration表示配置层

程序的工程分层,调用流程如下:

在这里插入图片描述

1.3.1 类注解之间的关系

查看@Controller、@Service、@Repository、@Configuration等注解可以发现:<img 在这里插入图片描述

这些类注解里面都有一个注解@Component,说明它们本身就属于@Component的“子类”

1.3.2 Bean命名规则

通过场面的例子我们可以看出,通常我们bean使用的都是标准大驼峰的命名,而读取的时候首字母小写就可以获取到bean了。

然后当我们首字母和第二个字母都大写的时候,就不能正常的读取到Bean了

这个时候我们就要查询Spring关于Bean存储时生成的命名规则了在这里插入图片描述

源码如下:

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);
}

1.4 方法注解

类注解是添加到某个类上的,而方法注解是放到某个方法当中,如以下代码实现:

public class UserBean {
    @Bean
    public void sayHi() {
        System.out.println("你好bean");
    }
}

但是我们发现根本获取不到。这是为什么?

1.4.1 方法注解要配合类注解来使用

在Spring框架当中,方法注解@Bean要配合类注解才能将对象正常的存储到Spring容器当中,如下代码:

@Component
public class UserBean {
    @Bean
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

1.4.2 重命名Bean

可以通过设置name属性给Bean对象进行重命名操作

@Component
public class UserBean {
    @Bean(name = "user")
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

Bean命名规则:当没有设置name属性的时候,那么bean默认的名称就是方法名,当设置了name属性之后,只能通过重命名的那么属性对应的值来获取。也就是说,重命名之后再使用方法名就获取不到了

2. 获取Bean对象(对象装配)

获取bean对象也叫对象装配,是把对象取出来放到某个类当中,也时候也叫作对象注入

对象装配的实现有以下3中方法:

  1. 属性注入
  2. 构造方法注入
  3. Setter注入

2.1 属性注入

在这里插入图片描述

2.2 构造方法注入

在这里插入图片描述

如果当前类当中只存在一个构造方法,那么@Autowired注解可以省略

2.3 Setter注入

在这里插入图片描述

2.4 三种注入的优缺点

  • 属性输入的优点是简介、使用方便;缺点是只能用于IOC容器,如果不是IOC容器不可用,并且只有在使用的时候才会出现NPE(空指针异常)
  • 构造方法注入是Spring推荐的注入方式。它的缺点是如果有多个注入会显得比较臃肿,但是出现这种情况应该考虑一下当前类是否符合程序的单一职责的设计模式了,它的有点在于通用性,在使用之前,一定能保证注入的类不为空
  • Setter方式是Spring前期版本推荐的注入方式,但是通用性不如构造方法,所有Spring版本已经推荐使用构造方法来注入了

2.5 @Resource:另一种注入关键字

@Autowired和@Resource的区别:

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

2.6 同一个类型多个@Bean报错

解决方案有以下两种:

  • 使用@Resource(name=“user1”)定义
  • 使用@Qualifier注解定义名称
@Controller
public class UserController5 {
    // 注⼊
    @Autowired
    @Qualifier(value = "user2")
    private User user;
    public User getUser() {
        return user;
    }
}

3. 总结

  1. 将对象存储到Spring中:
    1. 使用类注解:@Controller、@Service、@Repository、@Configuration、@Component【它们之间的关系】
    2. 使用方法注解:@Bean【注意事项:必须配合类注解一起使用】
  2. Bean的命名规则:首字母和第二个字母都不是大写,首字母小写来获取Bean,如果首字母和第二个字母都是大写,那么直接使用Bean名来获取Bean
  3. 从Spring中获取对象
    1. 属性注入
    2. Setter注入
    3. 构造方法注入(推荐)
  4. 注入的关键字有
    1. @Autowired
    2. @Resource
  5. @Autowired 和 @Resource 区别:出身不同;使用是设置参数不同@Resource支持更多的参数设置
  6. 解决同一个类型多个Bean的报错
    1. 使用@Resource(name = “”)
    2. 使用@Qualifier(“”)

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

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

相关文章

筑基七层 —— 数据在内存中的存储?拿来吧你

目录 零&#xff1a;移步 一.修炼必备 二.问题思考 三.整型在内存中的存储 三.大端字节序和小端字节序 四.浮点数在内存中的存储 零&#xff1a;移步 CSDN由于我的排版不怎么好看&#xff0c;我的有道云笔记相当的美观&#xff0c;请移步至有道云笔记 一.修炼必备 1.入门…

web客户端-websocket

1、websocket简介 WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。 WebSocket使得客户端和服务器之间的数据交换变得更加简单&#xff0c;允许服务端主动向客户端推送数据。在WebSocket API中&#xff0c;浏览器和服务器只需要完成一次握手&#xff0c…

一文教你把ChatGPT变成MySQL数据库,颠覆你的认知

ChatGPT是当前最热门的产品了,很多人已经在用ChatGPT问答、写文章、编程、做题甚至是通过了各种考试。今天我用几个步骤来带着大家体验如何把ChatGPT变成MySQL数据库。 首先,我们需要创建一个数据库,让chatgpt把自己当做一个数据库,可以给它一个定义: 你来充当一个mysql数…

自定义复杂图片水印

我的社交能力还不如5岁儿童和狗。 文章目录前言一、主要工具类总结前言 之前写过一些简单的图片压缩和图片加水印&#xff1a;JAVA实现图片质量压缩和加水印 本次主要是针对图片加水印进行一个升级&#xff0c;图片水印自定义&#xff0c;自适应大小。 来&#xff0c;先看几…

JS语法让人困惑的点 “==与===”

在JS中有很多神奇的语法&#xff0c;非常让人困惑&#xff0c;我们就先一一道来&#xff0c;相信你在开发中或多或少都踩过这些坑&#xff0c;或者让人无法理解。 今天我们就来说下【】和【】 这题对于很多没有系统学过前端开发的技术人员来说&#xff0c;算个重点&#xff0c…

LLFlow沦为和代码解读

LLFlow沦为和代码解读 1.测试时代码的运行位置 sr&#xff1a;什么意思 sr 和 z 这里又将模型设置为了训练模式 所以下面这部分代码应该是测试时运行的所有代码 这个就是测试时使用的网络模型框架 下面应该就是self.netG的网络模型框架 但是这个z的网络模型框架代码还不…

前端基础之HTML扫盲

文章目录一. 第一个HTML程序1. 创建一个HTML文件并运行2. HTML的基本结构二. HTML常见标签1. 注释标签2. 标题标签3. 段落标签4. 换行标签5. 格式化标签6. 图片标签7. 超链接标签8. 表格标签9. 列表标签10. 表单标签10.1 input标签10.2 select标签10.3 textarea标签11. 无语义标…

Outlook账号被封?别慌,一步步教你怎么申诉

相信很多兄弟们使用Outlook不止是为了注册第三方平台&#xff0c;很多时候还会用来发送一些营销广告。但是广告邮件发多了很容易被官方检测到并查封。龙哥考虑到这个问题&#xff0c;就干脆给兄弟们也出一份Outlook的申诉教程&#xff0c;保证大家都从注册、养号、防关联到解封…

DataGear 使用数据集计算属性功能制作数据可视化图表

DataGear 在4.5.0版本新增了数据集计算属性特性&#xff0c;支持在定义数据集时对原始数据进行二次计算处理。 利用这一特性&#xff0c;可以更加方便灵活地制作数据可视化图表。 本文以某公司近两年季度销售额Excel为例&#xff0c;介绍如何基于数据集计算属性功能制作数据可…

Vue跨级通信(重点)

当不使用Vuex的前提下&#xff0c;子孙传递就得使用另外一种办法&#xff1a;provide 和 inject 总结&#xff1a;provide / inject 类似于消息的订阅和发布。- inject接收数据。- provide提供或发送数据&#xff0c;&#xff08;1&#xff09;provide&#xff08;name&#xf…

Dubbo性能调优参数以及原理

Dubbo作为一个服务治理框架&#xff0c;功能相对来说比较完善&#xff0c;性能也挺不错。但很多同学在使用dubbo的时候&#xff0c;只是简单的参考官方说明进行配置和应用&#xff0c;并没有过多的去思考一些关键参数的意义&#xff0c;最终做出来的效果总是差强人意,接下来我们…

扬帆优配|反弹涨超70%,昨收三连板,稀土行业或迎大事件

本年第一批稀土挖掘锻炼目标行将发放。 2月22日晚&#xff0c;东易日盛公告称&#xff0c;公司收到董事、副总经理兼财务总监李双侠出具的《关于未严格执行股份减持方案的致歉函》&#xff0c;其此次减持方案已施行结束&#xff0c;但在施行减持方案时&#xff0c;因操作失误&a…

从没想过开源 API 工具的 Mock 功能,这么好用

很多时候&#xff0c;接口尚未开发完成&#xff0c;在系统交互双方定义好接口之后&#xff0c;我们可以提前进行开发和测试&#xff0c;并不依赖上游系统的开发实现。 通过使用Mock模拟数据接口&#xff0c;我们即可在只开发了UI的情况下&#xff0c;无须服务端的开发就可以进行…

证明CPU指令是乱序执行的

承接上文CPU缓存一致性原理双击QQ.exe从磁盘加载到内存里面&#xff0c;内存里面就会有了一个进程&#xff0c;进程产生的时候会产生一个主线程&#xff0c;就是main方法所在的线程&#xff0c;cpu会找到main开始的地方&#xff0c;把它的指令读取过来放到程序计数器&#xff0…

从功能测试进阶自动化测试,熬夜7天整理出这一份3000字超全学习指南

一、为什么要学习自动化测试&#xff1f; 如果在前两年&#xff0c;可能10个测试员有6个都是做的功能测试&#xff0c;但随着测试技术的发展以及测试工作的深入&#xff0c;传统的手工测试已经无法满足多模块的测试需求&#xff0c;所以为了提高测试效率和测试质量&#xff0c…

关于 mac 本地配置域名能 ping 通,但是浏览器不能访问的问题(而其他电脑操作可访问)

关于 mac 本地配置域名能 ping 通&#xff0c;但是浏览器不能访问的问题&#xff08;而其他电脑操作可访问&#xff09;1. 配置域名的方式1.1 sudo vim /etc/hosts1.2 浏览器插件 LiveHosts2. 问题描述3. 解决问题方法3.1 尝试方法1—确保代理都关闭3.2 尝试方法2—确保域名能p…

一文学会 Spring 整合 MyBatis

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

js闭包简单理解

js里面的闭包是一个难点也是它的一个特色&#xff0c;是我们必须掌握的js高级特性&#xff0c;那么什么是闭包呢&#xff1f;它又有什么作用呢&#xff1f; 1&#xff0c;提到闭包我们这里先讲解一下js作用域的问题 js的作用域分两种&#xff0c;全局和局部&#xff0c;基于我…

代码随想录第十六天(347、194、195、94)

347. 前 K 个高频元素 答案 思路&#xff1a; 1、首先&#xff0c;用到了每个值对应的出现次数&#xff0c;想到要用哈希map存放 2、还需要将出现频率从大到小进行排序&#xff0c;找出前k个元素 3、时间复杂度应该比O&#xff08;nlogn&#xff09;小 如果想用快速排序&…

黑盒渗透盲打lampiao

一、查找主机ip&#xff0c;通过Nmap扫描工具排查出我的靶机的IP 为.134 python tools.py ip -i 192.168.12.0 -h 254 -l 1 二、扫描其他端口。 1898 三、查看网站漏洞情况&#xff0c;典型的漏洞特征 Ac扫描漏洞情况&#xff0c;利用典型的漏洞。 四、开始getshell 1、启动M…