2. Spring 的创建和使用

目录

1. 创建 Spring 项目

1.1 创建一个 maven 项目

1.2 添加 Spring 框架支持

1.3 添加启动类

2. 存储 Bean 对象

2.1 创建 Bean

2.2 将 Bean 注册到容器

3. 获取并使用 Bean 对象

3.1 创建 Spring 上下文

 ApplicationContext 和 BeanFactory 的区别(重点) 

3.2 获取指定的 Bean 对象

3.2.1 通过 id 获取 

3.2.2 通过类型获取

3.2.3 通过 id + 类型 获取

3.3 使用 Bean

4. Spring 创建和使用总结

5. 根据日志定位问题

5.1 NoUniqueBeanDefinitionException -- 无唯一BeanDefinition异常

5.2  BeanDefinitionParsingException -- BeanDefinition解析异常

5.3 FileNotFoundException -- 文件未找到异常

5.4 NoSuchBeanDefinitionException -- 没有这样的对象


在上篇文章中,我们了解了 Spring 的核心与设计思想:Spring 是一个包含了众多工具方法的 IoC 容器。Spring 具备的两个功能:

  • 将对象存储到 Spring 中
  • 从 Spring 中将对象取出来

在 Java 中,对象也叫 Bean。

1. 创建 Spring 项目

接下来我们使用 maven 方式来创建一个 Spring 项目,分以下三步:

  1. 创建⼀个普通 Maven 项目
  2. 添加 Spring 框架支持spring-context、spring-beans)。
  3. 添加启动类

1.1 创建一个 maven 项目

1.2 添加 Spring 框架支持

在项⽬的 pom.xml 中添加 Spring 框架的⽀持,xml 配置如下:
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.2.3.RELEASE</version></dependency>
</dependencies>

添加以上代码后,刷新,显示如下图所示:

从上述配置中可以看出,添加的框架有 spring-context:spring 上下⽂,还有 spring-beans:管理对象的模块。

1.3 添加启动类

在创建好的项目 Java 文件夹下新创建一个包含 main 方法的启动类:

public class App {public static void main(String[] args) {}
}

2. 存储 Bean 对象

存储 Bean 分以下两步:

  1. 存储 Bean 之前,得先有 Bean,因此需要先创建一个 Bean
  2. 将创建的 Bean 注册到 Spring 容器中

2.1 创建 Bean

所谓的 Bean 是Java 语言中的一个普通对象,实现代码如下:

public class User {public String sayHi(String name){return name + "Hi";}
}

2.2 将 Bean 注册到容器

在创建好的项目中添加 Spring 配置文件 spring-config.xml,将此文件放到 resources 的根目录下, 如下图所示:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>
接下来,再将 User 对象注册到 Spring 中就可以,具体操作是在 <beans> 中添加如下配置:
<bean id="" class=""></bean>

id 我们设置为 user,class 后应为全限定名,即带路径的名称。

那么如何知道我们的路径是否正确呢?

按住 CTRL键 鼠标点击 User 可以跳转到 User 类,则说明路径正确。

3. 获取并使用 Bean 对象

获取并使用 Bean 对象分为以下3步:

  1. 得到 Spring 上下文对象(因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就需要得到 Spring 上下文)
  2. 通过 Spring 上下文,获取某一个指定的对象
  3. 使用 Bean 对象 

如果获取多个 Bean 则重复第2、3步骤。

3.1 创建 Spring 上下文

ApplicationContext 可以认为是 Spring 的运行环境,翻译过来就是上下文。

使用 ApplicationContext 创建 Spring 的上下文对象,创建的时候需要配置 Spring 配置信息:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

除了 ApplicationContext 我们还可以使用 BeanFactory 来获取 Spring 的上下文:

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
 ApplicationContext 和 BeanFactory 的区别(重点) 

 ApplicationContext 和 BeanFactory 效果是一样的,ApplicationContext 属于 BeanFactory 的子类,它们有以下区别

  • 继承关系功能方面:Spring 容器有两个顶级的接口:BeanFactory 和 ApplicationContext. 其中 BeanFactory 提供了基础的访问容器的能力,而 ApplicationContext 属于 BeanFactory 的子类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化支持、资源访问支持、以及事件传播等方面的支持
  • 性能方面来说:ApplicationContext 是一次性加载并初始化所有的 Bean 对象(空间换时间),而 BeanFactory 是需要哪个才加载哪个(懒加载),因此更加轻量。

CalssPathXmlApplicationContext 属于 ApplicationContext 的子类,拥有 ApplicationContext 的所有功能,是通过 xml 的配置来获取所有 Bean 的。

3.2 获取指定的 Bean 对象

通过以下几种方法可以获取 Bean,最常用的为上面三种:

3.2.1 通过 id 获取 
User user = (User)context.getBean("user"); // 通过 Id 获取

需要注意的是,Id 是唯一的,Bean 的 Id 需要一一对应

3.2.2 通过类型获取
// 通过类名获取
User user = context.getBean(User.class);

优点:不需要进行类型转换

缺点:如果一个类有多个对象时,不能使用该方式 

3.2.3 通过 id + 类型 获取
// 通过 id + 类型获取
User user = context.getBean("user",User.class);

那么 通过类型获取 Bean 和 id + 类型 获取 Bean 有什么区别呢?

区别:当有⼀个类型被重复注册到 spring-config.xml 中时,只能使用根据名称获取了,比如以

下程序:

错误日志:
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'BuildSpring.User' available: expected single matching bean but found 2: user,user2

可以看到错误日志大致为:期待找到一个匹配的 bean 但是 找到了两个分别是:user 和 user2.

User user = (User)context.getBean("user");
System.out.println(user);
User user1 = (User)context.getBean("user");
System.out.println(user1);
User user2 = context.getBean(User.class);
System.out.println(user2);
User user3 = context.getBean("user",User.class);
System.out.println(user3);

可以看到,无论获取多少次对象或者使用哪种方式获取,依然拿到的是同一个 Bean。

3.3 使用 Bean

public class App {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));// 通过 ID 获取User user = (User)context.getBean("user");// 通过类名获取
//        User user = context.getBean(User.class);// 通过 id + 类型获取
//        User user = context.getBean("user",User.class);System.out.println(user.sayHi("小明"));}
}

4. Spring 创建和使用总结

Spring 的创建和使用的整体流程为:

  1. Spring 项目的创建
    1. 创建项目
    2. 引入依赖
    3. 创建一个启动类
  2. 存对象
    1. 创建 Bean(类)
    2. 将 Bean 注册到 spring-config 中
  3. 取对象
    1. 得到 Spring 的上下文,并读取到 Spring 的配置文件(ApplicationContext)
    2. 获取某一个 Bean 的对象(getBean())
    3. 使用 Bean 对象

5. 根据日志定位问题

日志只有一段时只看一段的最前面就可以(从上往下看),当有多段时从下往上看。

5.1 NoUniqueBeanDefinitionException -- 无唯一BeanDefinition异常

Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'BuildSpring.User' available: expected single matching bean but found 2: user,user2

 期待找到一个匹配的 bean 但是找到了两个分别是:user 和 user2。

5.2  BeanDefinitionParsingException -- BeanDefinition解析异常

Exception in thread "main" org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'user' is already used in this <beans> element
Offending resource: class path resource [spring-config.xml]

Bean名称“user”已在此<beans>元素路径资源[spring config.xml]中使用。

5.3 FileNotFoundException -- 文件未找到异常

 Caused by: java.io.FileNotFoundException: class path resource [spring-config1.xml] cannot be opened because it does not exist
    at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
    at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:331)
    ... 13 more

[spring-config1.xml]无法打开,因为它不存在。

5.4 NoSuchBeanDefinitionException -- 没有这样的对象

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'user1' available

没有名为“user1”的bean可用。

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

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

相关文章

分布式锁:Redis、Zookeeper

1.基于Redis实现分布式锁&#xfeff; Redis分布式锁原理如上图所示&#xff0c;当有多个Set命令发送到Redis时&#xff0c;Redis会串行处理&#xff0c;最终只有一个Set命令执行成功&#xff0c;从而只有一个线程加锁成功 2.SetNx命令加锁 利用Redis的setNx命令在Redis数据库…

MySQL数据库关于表的一系列操作

MySQL中的数据类型 varchar 动态字符串类型&#xff08;最长255位&#xff09;&#xff0c;可以根据实际长度来动态分配空间&#xff0c;例如&#xff1a;varchar(100) char 定长字符串&#xff08;最长255位&#xff09;&#xff0c;存储空间是固定的&#xff0c;例如&#…

系统架构设计师-软件架构设计(4)

目录 一、软件架构评估 1、敏感点 2、权衡点 3、风险点 4、非风险点 5、架构评估方法 5.1 基于调查问卷或检查表的方式 5.2 基于度量的方式 5.3 基于场景的方式 6、基于场景的评估方法 6.1 软件架构分析法&#xff08;SAAM&#xff09; 6.2 架构权衡分析法&#xff08;ATAM&am…

J2EE通用分页02

目录 一.重构-提取公用方法 1.为了进行公共方法的抽取&#xff0c;需要找出上面实习中的可通用部分&#xff0c;和差异化部分 2.公用方法封装思路 3. 具体实现 二.分页标签 2.1 准备一个Servlet 3.2 结果展示页面 三. 过滤器解决中文乱码问题 四.加入分页功能 四…

Clion开发STM32之W5500系列(NTP服务封装)

概述 在w5500基础库中进行封装&#xff0c;获取服务端的时间&#xff0c;来校准本地时间。本次使用的方案是通过ntp获取时间定时器更新保证时间准确。 NTP封装 头文件 /*******************************************************************************Copyright (c) [sc…

2:SpringIOC

文章目录 一&#xff1a;Spring_IOC概念引入_重要1&#xff1a;Spring解耦合的原理2&#xff1a;创建一个spring项目并实现IOC基本功能 二&#xff1a;Spring_IOC原理分析 ***1&#xff1a;XML解析技术读取配置文件**2**&#xff1a;反射技术实例化对象,放到容器中3&#xff1a…

【算法训练营】字符串转成整数

字符串转成整数 题目题解代码 题目 点击跳转: 把字符串转换为整数 题解 【题目解析】&#xff1a; 本题本质是模拟实现实现C库函数atoi&#xff0c;不过参数给的string对象 【解题思路】&#xff1a; 解题思路非常简单&#xff0c;就是上次计算的结果10&#xff0c;相当于10…

【大数据之Flume】三、Flume进阶之Flume Agent 内部原理和拓扑结构

1 Flume事务 2 Flume Agent 内部原理 重要组件&#xff1a; 1、ChannelSelector&#xff08;选择器&#xff09;   ChannelSelector 的作用就是选出 Event 将要被发往哪个 Channel。   &#xff08;1&#xff09;Replicating ChannelSelector&#xff08;复制或副本&#x…

格式工厂5.10.0版本安装

目前格式工厂有很多&#xff0c;大多都可以进行视频转换 之前遇到一个用ffmpeg拉流保存的MP4在vlc和迅雷都无法正常播放的问题&#xff0c;发现视频长度不对&#xff0c;声音也不对&#xff0c;最后换到了格式工厂的格式播放器是可以正常播放的 格式工厂下载之家的地址 http…

每天五分钟计算机视觉:单卷积层的前向传播过程

什么是单卷积层? 一张图片(输入)经过多个卷积核卷积就会得到一个输出,而这多个卷积核的组合就是一个单卷积层。 这些卷积核可能大小是不一样的,但是他们接收同样大小是输入,他们的输出必须是一般大小,所以不同的卷积核需要具备不同的步长和填充值。 单层卷积网络前向传…

你们公司的【前端项目】是如何做测试的?字节10年测试经验的我这样做的...

前端项目也叫web端项目&#xff08;通俗讲就是网页上的功能&#xff09;是我们能够在屏幕上看到并产生交互的体验。 前端项目如何做测试&#xff1f; 要讲清楚这个问题&#xff0c;先需要你对测试流程现有一个全局的了解&#xff0c;先上一张测试流程图&#xff1a; 测试流程…

旧版Xcode文件较大导致下载总是失败但又不能断点续传重新开始的解决方法

问题&#xff1a; 旧版mac下载旧版Xcode时需要进入https://developer.apple.com/download/all/?qxcode下载&#xff0c;但是下载这些文件需要登录。登录后下载中途很容易失败&#xff0c;失败后又必须重新下载。 解决方案&#xff1a; 下载这里面的内容都需要登录&#xff0…

开发一个RISC-V上的操作系统(二)—— 系统引导程序(Bootloader)

目录 文章传送门 一、什么是Bootloader 二、简单的启动程序 三、上板测试 文章传送门 开发一个RISC-V上的操作系统&#xff08;一&#xff09;—— 环境搭建_riscv开发环境_Patarw_Li的博客-CSDN博客 开发一个RISC-V上的操作系统&#xff08;二&#xff09;—— 系统引导…

机器学习深度学习——多层感知机

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——感知机 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们有所帮助 上一节…

Git时间:版本控制工具进阶

Git时间&#xff1a;版本控制工具进阶 忽略文件 Git允许用户将指定的文件或目录排除在版本控制之外&#xff0c;它会检查代码仓库的目录下是否存在一个名为.gitignore的文件&#xff0c;如果存在&#xff0c;就去一行行读取这个文件中的内容&#xff0c;并把每一行指定的文件…

MySQL 读写分离

目录 一、什么是读写分离&#xff1f; 二、为什么要读写分离呢&#xff1f; 三、什么时候要读写分离&#xff1f; 四、主从复制与读写分离 五、MySQL 读写分离原理 六、企业 使用MySQL 读写分离场景 1&#xff09;基于程序代码内部实现 2&#xff09;基于中间代理层实现…

你说你会Java手动锁,但你会这道题吗???

按照这个格式输出你会吗&#xff1f;&#xff1f;&#xff1f; 你说你不会&#xff0c;接下来认真看认真学了。 1.首先引入原子类。AtomicInteger num new AtomicInteger(0); 什么是原子类&#xff1f; 就是可以保证线程安全的原子操作的数据类型。 有什么作用&#xff1f;…

在Debian 12 上安装 PHP 5.6, 7.4

环境&#xff1a;Debian 12 Debian 12 默认的PHP版本为 8.2 如果直接安装php7.4就出现下面的报错&#xff1a; sudo apt-get install libapache2-mod-php7.4 php7.4 php7.4-gd php7.4-opcache php7.4-mbstring php7.4-xml php7.4-json php7.4-zip php7.4-curl php7.4-imap p…

导出为PDF加封面且分页处理dom元素分割

文章目录 正常展示页面导出后效果代码 正常展示页面 导出后效果 代码 组件内 <template><div><div><div class"content" id"content" style"padding: 0px 20px"><div class"item"><divstyle"…

Ubuntu Server版 之 mysql 系列

Ubuntu 分 桌面版 和 服务版 桌面版 &#xff1a;有额外的简易界面 服务版&#xff1a;是纯黑框的。没有任何UI界面的可言 安装mysql 安装位置 一般按照的位置存放在 /usr/bin 中 sudo apt-get install mysql-server查看mysql的状态 service mysql status mysql 安全设置…