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,一经查实,立即删除!

相关文章

django项目入门

django中view.py是什么 在Django中&#xff0c;view.py是一个Python模块&#xff0c;用于处理HTTP请求并返回HTTP响应。它包含了Django应用程序的视图函数&#xff0c;视图函数接收HTTP请求作为参数&#xff0c;并根据请求的内容执行相应的逻辑处理。视图函数可以从数据库中获…

gitignore修改不生效

.gitignore中已经标明忽略的文件目录下的文件&#xff0c;当我想git push的时候还会出现在push的目录中&#xff0c;原因是因为在git忽略目录中&#xff0c;新建的文件在git中会有缓存&#xff0c;如果某些文件已经被纳入了版本管理中&#xff0c;就算是在.gitignore中已经声明…

Jenkins Pipeline的hasProperty函数

函数的作用 用于判断某个参数或者字段是否存在。 用法 例子一 def projectStr "P1,P2,P3" pipeline {agent anyparameters {extendedChoice(defaultValue: "${projectStr}",description: 选择要发布的项目,multiSelectDelimiter: ,,name: SELECT_PROJ…

学习Java,需要知道的网站30+网站,你知道哪些?

以下是 30 个 Java 学习网站&#xff0c;并详细介绍&#xff1a; Java 官方文档&#xff1a;https://docs.oracle.com/javase/8/docs/api/ Java 官方文档是 Java 学习者必备的参考资料&#xff0c;提供了 Java 核心库的详细说明和示例代码&#xff0c;包括类、接口、方法和属性…

分布式锁:Redis、Zookeeper

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

TensorFlow 进阶:定制模型和训练算法

本文将为你提供关于 TensorFlow 的中级知识&#xff0c;你将学习如何通过子类化构建自定义的神经网络层&#xff0c;以及如何自定义训练算法。 一、创建自定义层 在 TensorFlow 中&#xff0c;神经网络的每一层都是一个类&#xff0c;我们可以通过创建一个新的类并继承 tf.ke…

Vision Transformer (ViT)

生成式模型与判别式模型 生成式模型&#xff0c;又称概率模型&#xff0c;是指通过学习数据的分布来建立模型P(y|x)&#xff0c;然后利用该模型来生成新的数据。生成式模型的典型代表是朴素贝叶斯模型&#xff0c;该模型通过学习数据的分布来建立概率模型&#xff0c;然后利用…

【个人笔记】Linux命令之查看使用过的命令

1.使用 history 显示出所有使用过的命令 history2.使用 history 和 grep 命令进行过滤 history | grep docker3.查看 &#xff5e;/.bash_history 文件&#xff0c;Bash的命令历史默认保存在~/.bash_history中 vim ~/.bash_history #或 cat -n ~/.bash_history4.使用 ctrlr …

【人工智能】深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化) 文章目录 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化)深度神经网络训练训练深度神经网络参数共享卷积神经网络(CNN)卷积多卷积核卷积全连接最大池化卷积+池化拉平向量激活函数优化小结深度神经…

如何在Debian中配置代理服务器?

开始搭建代理服务器 首先我参考如下文章进行搭建代理服务器&#xff0c;步骤每一个命令都执行过报了各种错&#xff0c;找了博客 目前尚未开始&#xff0c;我已经知道我的路很长&#xff0c;很难走呀&#xff0c;加油&#xff0c;go&#xff01;go&#xff01;go&#xff01; …

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

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

Nginx | Nginx返回的状态码详情

200 &#xff08;成功&#xff09; 服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。 201 &#xff08;已创建&#xff09; 请求成功并且服务器创建了新的资源。 202 &#xff08;已接受&#xff09; 服务器已接受请求&#xff0c;但尚未处理。 203 &…

博客更新notion版本01

官网视频娇嗔 Your connected workspace for wiki, docs & projects | Notion 【Notion教程】&#xff1a;https://www.bilibili.com/video/[BV1so4y1V7nX](https://www.bilibili.com/video/BV1so4y1V7nX/?spm_id_from333.788.video.desc.click) 【Notion汉化】&#x…

系统架构设计师-软件架构设计(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 结果展示页面 三. 过滤器解决中文乱码问题 四.加入分页功能 四…

Visio制作特征矩阵

Visio制作特征矩阵 https://blog.csdn.net/sinat_39620217/article/details/115577962?ops_request_misc&request_id&biz_id102&utm_termvisio%E6%9C%89%E7%BD%91%E6%A0%BC%E5%90%97&utm_mediumdistribute.pc_search_result.none-task-blog-2allsobaiduweb~de…

Yolov8引入 清华 ICCV 2023 最新开源移动端网络架构 RepViT | RepViTBlock即插即用,助力检测

💡💡💡本文独家原创改进:轻量级 ViT 的高效架构选择,逐步增强标准轻量级 CNN(特别是 MobileNetV3)的移动友好性。 最终产生了一个新的纯轻量级 CNN 系列,即 RepViT RepViTBlock即插即用,助力检测 | 亲测在多个数据集能够实现涨点,并实现轻量化 💡💡💡Yo…

Unity UGUI的StandaloneInputModule (标准输入模块)组件的介绍及使用

Unity UGUI的StandaloneInputModule (标准输入模块)组件的介绍及使用 1. 什么是StandaloneInputModule组件&#xff1f; StandaloneInputModule是Unity UGUI系统中的一个标准输入模块组件&#xff0c;用于处理鼠标和键盘的输入事件。它可以将鼠标和键盘的输入转化为UGUI系统中…

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…