当前位置: 首页 > news >正文

2. Spring的创建和Bean的存取

经过前面的学习我们已经大体明白了 IOC 思想以及它的实现方式 DI ,本节要讲的是如何Spring框架实现实现DI。

本节目标:

  1. Spring(Core) 项目创建
  2. 将对象存储到 Spring 中
  3. 将对象(bean)从 Spring 中取出

1. 创建 Spring 项目

与开篇演示的 Spring Boot 项目不同,罗马城不是一天建成的,Spring Boot 出来之前还是需要使用 Maven 构建一个 Spring 项目,与 Servlet 类似,但由于 IOC 和 DI 的加持,又更胜Servlet一筹,Spring 项目的创建分为以下三步:

  1. 创建一个普通Maven项目;
  2. 添加Spring框架依赖 spring-context、spring-beans(可以将spring-context理解为Spring本身,存储在Spring称之为bean,也就是spring-beans);
  3. 添加启动类;

1.1 创建Maven项目

1.2 添加Spring 框架依赖

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.9.RELEASE</version>
</dependency>

添加完依赖记得检查一下:

image.png

1.3 添加启动类

2. 存储Bean对象

并不是真的存储,而是告诉Spring,此Bean需要托管给Spring

2.1 创建bean对象

Bean对象其实就是Java语言中的一个普通对象

public class UserBean {public void sayHi() {System.out.println("Hi!");}
}

2.2 创建配置文件

resource目录下创建一个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">
</beans>

2.3 注册bean

image.png

<bean id="user" class="UserBean"></bean>

解释:bean的id是自己命名的,命名规范同样是小驼峰,取bean的时候会用到。class对应的就是自己创建的bean对象(包名+类名),我这里没有放包里,因此直接就是UserBean

3. 从 Spring 中取出 bean对象

3.1 得到Spring的上下文对象

public class Application {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");}
}

ApplicationContext是一个接口,ClassPathXmlApplicationContext是它的实现类,由此得到Spring context对象

3.2 从Spring上下文中取出对象

getbean有如下这么多方法,这里先用最简单的通过beanId来获取bean对象:

//getbean方法里面的参数就是配置文件中bean对象的id
UserBean user = (UserBean)context.getBean("user");

3.3 使用bean对象

image.png

至此我们全程都没有使用过new对象的方式,成功从Spring中取出bean对象

3.4 理解bean的实例化

根据bean的class来获取bean

//1.根据一个String 参数获取bean
//UserBean user = (UserBean)context.getBean("user");
//2.根据一个Class 参数获取bean
UserBean user = context.getBean(UserBean.class);

由于传了UserBean.class这种方法不需要强转就能获取到bean,运行结果:

image.png

修改配置文件:

<bean id="user1" class="UserBean"></bean>
<bean id="user2" class="UserBean"></bean>

报错了,意思大概是找到了预料之外的两个bean对象user1、user2:
image.png

我们用第一种方式来查看一下两个bean对象的地址:

UserBean user1 = (UserBean)context.getBean("user1");
UserBean user2 = (UserBean)context.getBean("user2");
System.out.println("user1:" + user1);
System.out.println("user2:" + user2);

结果发现bean的id不同,即便他们是一个类,还是会实例化两个对象:

image.png

区分单例模式:单例模式指的是每一个bean对象都是单例的,而不是说一种类只能存在一个bean对象。

//取两次id为user1的bean,地址一样
UserBean user1 = (UserBean)context.getBean("user1");
UserBean user1Test = (UserBean)context.getBean("user1");UserBean user2 = (UserBean)context.getBean("user2");System.out.println("user1:" + user1);
System.out.println("user1Test:" + user1Test);
System.out.println("user2:" + user2);

结果发现确实是单例的:

image.png

4. Spring上下文对象

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

除了上面的那种写法,获取上下文对象还可以用下面这种写法——BeanFactory:

BeanFactory context = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

ApplicationContext 和 BeanFactory 的关系(面试常考)

共同点:都是用来获取Spring上下文对象

不同点:

  • 继承和功能:ApplicationContext 是 BeanFactory 的子接口,ApplicationContext具备了BeanFactory的所有功能。BeanFactory 只具备最基础访问bean的能力,ApplicationContext 具备更多能力,比如国际化支持、资源访问支持、以及事件传播等方面的支持。
  • 性能和加载方式 :ApplicationContext是饿汉模式一次性加载完所有Bean对象,BeanFactory是懒汉模式按需加载,更加轻量。随着硬件资源的升级,在资源充裕的情况下推荐使用ApplicationContext,使用户第一次使用bean对象时节省实例化bean对象并存储到Spring的开销。

5. 总结

Spring的创建和使用的过程:

  1. 创建Spring项目
  • 创建一个 Maven 项目
  • 添加 Spring 依赖
  • 创建一个启动类
  1. 将对象存储到 Spring
  • 创建一个 bean 对象
  • 创建配置 .xml 文件
  • 将 bean 注册到 Spring 的配置文件(id用于取对象,class表示存储bean的位置)

image.png

  1. 从Spring中取出 bean 对象
  • 先得到 Spring 上下文对象
  • 从 Spring 中取出bean对象并使用

这样使用Spring让我们初步理解到了DI的实现方式,但是我们发现并不便利,下一章节我们学习使用Spring的注解方式,让Spring框架更加简洁好用。

http://www.lryc.cn/news/338717.html

相关文章:

  • 策略模式【行为模式C++】
  • php中session相关知识(目前了解部分)
  • 从零实现诗词GPT大模型:GPT是怎么生成内容的?
  • 8路HDMI+8路AV高清视频流媒体编码器JR-3218HD
  • LangChain入门:14.LLMChain:最简单的链的使用
  • 深入理解k8s kube-proxy
  • Spark-机器学习(1)什么是机器学习与MLlib算法库的认识
  • java的正则表达式校验,包含了中国几乎所有运营商手机号码的校验格式
  • C#简单工厂模式的实现
  • .NET 设计模式—观察者模式(Observer Pattern)
  • EasyUI Jquery 学习笔记 ——DataGrid(数据网格)与 Tree(树)详细版
  • JAVA发票验真接口、票据ocr、数电票在线查验真伪
  • el-date-picker调用回车事件
  • js学习总结
  • MES实施优势有哪些?MES制造执行系统的主要内容
  • ChatGPT 和 Elasticsearch:使用 Elastic 数据创建自定义 GPT
  • 废品回收 小程序+APP
  • 下载好了annaconda,但是在创建一个新的Conda虚拟环境报错
  • 如何安装MacOS的虚拟机?mac安装虚拟机的步骤 虚拟机安装MacOS VMware Fusion和Parallels Desktop19
  • Flutter 中 AutomaticKeepAliveClientMixin 的介绍及使用
  • 注意力机制篇 | YOLOv8改进之清华开源ACmix:自注意力和CNN的融合 | 性能速度全面提升
  • Go语言支持重载吗?如何实现重写?
  • Spring中基于事件监听驱动 和 线程池的异步任务
  • C++ 优先级队列用法详解与模拟实现
  • Linux进阶之旅:深入探索Linux的高级功能
  • 【Java】内存可见性问题是什么?
  • Guava里一些比较常用的工具
  • 在windows系统中【.gz.tar】和【.whl】文件分别应该怎么下载到conda的某个虚拟环境中
  • Rust - 数据类型
  • 基于springboot实现洗衣店订单管理系统项目【项目源码+论文说明】计算机毕业设计