在您的应用程序中,由 Spring IoC 容器管理的形成其核心的对象被称为 "bean"。一个 bean 是由 Spring IoC 容器实例化、组装和管理的对象

这些 bean 是通过您提供给容器的配置元数据创建的。Bean 定义包含了所谓的配置元数据,容器需要了解以下内容:

  • 如何创建一个 bean
  • Bean 的生命周期详细信息
  • Bean 的依赖关系

上述所有的配置元数据都转化为每个 bean 定义的以下属性集合。

序号 属性和描述
1 class
这是必填属性,指定要用于创建 beanbean 类。
2 name
此属性唯一地指定 bean 标识符。在基于 XML 的配置元数据中,您可以使用 id 和/或 name 属性来指定 bean 标识符。
3 scope
此属性指定从特定 bean 定义创建的对象的范围
4 constructor-arg
这用于注入依赖项
5 properties
这用于注入依赖项
6 autowiring mode
这用于注入依赖项
7 lazy-initialization mode
延迟初始化的 bean 告诉 IoC 容器在首次请求时创建 bean 实例,而不是在启动时创建。
8 initialization method
在容器设置了 bean 的所有必需属性之后,要调用的回调函数
9 destruction method
在包含 bean 的容器销毁时要使用的回调函数

Spring 配置元数据

Spring IoC 容器与实际编写配置元数据的格式完全解耦。以下是向 Spring 容器提供配置元数据的三种重要方法:

  • 基于 XML 的配置文件。
  • 基于注解的配置。
  • 基于 Java 的配置。

您已经看到了如何将基于 XML 的配置元数据提供给容器,但让我们看一下包含不同 bean 定义的 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"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 一个简单的 `bean` 定义 -->
<bean id = "..." class = "...">
<!-- 此处是该 `bean` 的协作者和配置 -->
</bean> <!-- 启用延迟初始化的 `bean` 定义 -->
<bean id = "..." class = "..." lazy-init = "true">
<!-- 此处是该 `bean` 的协作者和配置 -->
</bean> <!-- 具有初始化方法的 `bean` 定义 -->
<bean id = "..." class = "..." init-method = "...">
<!-- 此处是该 `bean` 的协作者和配置 -->
</bean> <!-- 具有销毁方法的 `bean` 定义 -->
<bean id = "..." class = "..." destroy-method = "...">
<!-- 此处是该 `bean` 的协作者和配置 -->
</bean> <!-- 更多的 `bean` 定义在此处 -->

Spring 中的 Bean 作用域

在定义 <bean> 时,您可以选择为该 bean 声明一个作用域。例如,要强制 Spring 每次需要时生成新的 bean 实例,您应该将 bean 的作用域属性声明为 prototype。类似地,如果您希望 Spring 每次需要时返回相同的 bean 实例,您应该将 bean 的作用域属性声明为 singleton

Spring 框架支持以下五种作用域,其中三种仅在使用与 Web 相关的 ApplicationContext 时才可用。

序号 作用域 & 描述
1 singleton
bean 定义的作用域限制为 Spring IoC 容器中的单个实例(默认)。
2 prototype
将单个 bean 定义的作用域限制为具有任意数量的对象实例。
3 request
bean 定义的作用域限制为 HTTP 请求。仅在具有与 Web 相关的 Spring ApplicationContext 的情况下有效。
4 session
bean 定义的作用域限制为 HTTP 会话。仅在具有与 Web 相关的 Spring ApplicationContext 的情况下有效。
5 global-session
bean 定义的作用域限制为全局 HTTP 会话。仅在具有与 Web 相关的 Spring ApplicationContext 的情况下有效。

当讨论与

Web 相关的 Spring ApplicationContext 时,将讨论其他三种作用域。

单例作用域(singleton

如果将作用域设置为 singletonSpring IoC 容器将创建一个对象的确切实例,该实例由 bean 定义定义。此单个实例存储在此类单例 bean 的缓存中,对于该命名 bean 的所有后续请求和引用都会返回缓存的对象。

默认作用域始终是 singleton。但是,当您需要一个且仅一个 bean 实例时,您可以在 bean 配置文件中将作用域属性设置为 singleton,如下所示:

<!-- 具有 `singleton` 作用域的 `bean` 定义 -->
<bean id="..." class="..." scope="singleton">
<!-- 此处放置此 `bean` 的协作者和配置 -->

示例

假设您已经准备好 Eclipse IDE,并采取以下步骤创建 Spring 应用程序:

步骤

  1. 创建一个名为 SpringExample 的项目,在创建的项目中的 src 文件夹下创建一个名为 com.tutorialspoint 的包
  2. 使用"Add External JARs"选项添加所需的 Spring
  3. com.tutorialspoint 包下创建 JavaHelloWorldMainApp
  4. src 文件夹下创建 Beans 配置文件 Beans.xml
  5. 最后一步是创建所有 Java 文件和 Bean 配置文件的内容,并按以下说明运行应用程序。

以下是 HelloWorld.java 文件的内容:

package com.tutorialspoint;

public class HelloWorld {
private String message; public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}

以下是 MainApp.java 文件的内容:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A");
objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}

以下是 singleton 作用域所需的 Beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" scope="singleton">
</bean> </beans>

当您完成创建源代码和 bean 配置文件后,让我们运行应用程序。如果您的应用程序一切正常,它将打印以下消息:

Your Message : I'm object A
Your Message : I'm object A

原型作用域(prototype

如果将作用域设置为 prototypeSpring IoC 容器将在每次请求特定 bean 时创建该对象的新 bean 实例。通常,对于所有有状态的 bean,使用 prototype 作用域,对于无状态的 bean,使用 singleton 作用域。

要定义原型作用域,您可以在 bean 配置文件中将作用域属性设置为 prototype,如下所示:

<!-- 具有 `prototype` 作用域的 `bean` 定义 -->
<bean id="..." class="..." scope="prototype">
<!-- 此处放置此 `bean` 的协作者和配置 -->
</bean>

示例

假设您已经准备好 Eclipse IDE,并采取以下步骤创建 Spring 应用程序:

步骤

  1. 创建一个名为 SpringExample 的项目,在创建的项目中的 src 文件夹下创建一个名为 com.tutorialspoint 的包
  2. 使用"Add External JARs"选项添加所需的 Spring
  3. com.tutorialspoint 包下创建 JavaHelloWorldMainApp
  4. src 文件夹下创建 Beans 配置文件 Beans.xml
  5. 最后一步是创建所有 Java 文件和 Bean 配置文件的内容,并按以下说明运行应用程序。

以下是 HelloWorld.java 文件的内容:

package com.tutorialspoint;

public class HelloWorld {
private String message; public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}

以下是 MainApp.java 文件的内容:

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
HelloWorld objA = (HelloWorld) context.getBean("helloWorld"); objA.setMessage("I'm object A");
objA.getMessage(); HelloWorld objB = (HelloWorld) context.getBean("helloWorld");
objB.getMessage();
}
}

以下是 prototype 作用域所需的 Beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="helloWorld" class="com.tutorialspoint.HelloWorld" scope="prototype">
</bean> </beans>

当您完成创建源代码和bean配置文件后,让我们运行应用程序。如果您的应用程序一切正常,它将打印以下消息:

Your Message : I'm object A
Your Message : I'm object A

最后

为了方便其他设备和平台的小伙伴观看往期文章:

微信公众号搜索:Let us Coding,关注后即可获取最新文章推送

看完如果觉得有帮助,欢迎 点赞、收藏、关注

掌握 Spring IoC 容器与 Bean 作用域:详解 singleton 与 prototype 的使用与配置的更多相关文章

  1. spring IOC容器实例化Bean的方式与RequestContextListener应用

    spring IOC容器实例化Bean的方式有: singleton 在spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在. prototype 每次从容器中调用Bean时, ...

  2. spring-framework-中文文档一:IoC容器、介绍Spring IoC容器和bean

    5. IoC容器 5.1介绍Spring IoC容器和bean 5.2容器概述 本章介绍Spring Framework实现控制反转(IoC)[1]原理.IoC也被称为依赖注入(DI).它是一个过程, ...

  3. Spring IOC容器创建bean过程浅析

    1. 背景 Spring框架本身非常庞大,源码阅读可以从Spring IOC容器的实现开始一点点了解.然而即便是IOC容器,代码仍然是非常多,短时间内全部精读完并不现实 本文分析比较浅,而完整的IOC ...

  4. Spring IoC 容器和 bean 对象

    程序的耦合性: 耦合性(Coupling),又叫耦合度,是对模块间关联程度的度量.耦合的强弱取决于模块间接口的复杂性.调用模块的方式以及通过界面传送数据的多少.模块间的耦合度是指模块之间的依赖关系,包 ...

  5. spring IOC 容器中 Bean 的生命周期

    IOC 容器中 Bean 的生命周期: 1.通过构造器或工厂方法创建 Bean 实例 2.为 Bean 的属性设置值和对其他 Bean 的引用 3.调用 Bean 后置处理器接口(BeanPostPr ...

  6. Spring IOC容器中Bean的生命周期

    1.IOC容器中Bean的生命周期 构造器函数 设置属性 初始化函数(在Bean配置中 init-method) 使用Bean 结束时关闭容器(在Bean中配置destroy-method) 2.Be ...

  7. Spring IOC容器对bean的生命周期进行管理的过程

    1.通过构造器或者工厂方法创建bean的实例 2.为bean的属性设置值和对其他bean的引用 3.将bean的实例传递给bean的后置处理器BeanPostProcessor的postProcess ...

  8. Spring基础——在 IOC 容器中 Bean 之间的关系

    一.在 Spring IOC 容器中 Bean 之间存在继承和依赖关系. 需要注意的是,这个继承和依赖指的是 bean 的配置之间的关系,而不是指实际意义上类与类之间的继承与依赖,它们不是一个概念. ...

  9. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  10. Spring(十二):IOC容器中Bean的生命周期方法

    IOC容器中Bean的生命周期方法 1)Spring IOC容器可以管理Bean的声明周期,Spring允许在Bean生命周期的特定点执行定制的任务. 2)Spring IOC容器对Bean的生命周期 ...

随机推荐

  1. java个人博客

    效果浏览 首页 详情页 Aboutme 后台管理 管理/添加博客 添加分类 管理员管理 友情链接 访问地址 前台地址http://localhost 后台地址:http://localhost/adm ...

  2. git修改地址三种方法

    1.修改命令 git remote set-url origin [NEW_URL] 2.先删后加 git remote rm origin git remote add origin [url]3. ...

  3. 【Azure 事件中心】Event Hubs如何获取其中存放的历史消息

    问题描述 使用Azure Event Hub服务,除了正常的生产,消费消息以外,如果想拿到Event Hub中存储的历史消息?有什么方法呢? 问题解答 获取 Event Hubs 存储的历史消息,首先 ...

  4. Task Manager 的设计简述

    讲解 Task Manager 之前,在这里先介绍一些 Task Manager 会使用到的概念术语. 图数据库 Nebula Graph 中,存在一些长期在后台运行的任务,我们称之为 Job.存储层 ...

  5. map 简单梳理【GO 基础】

    〇.map 简介 map 是一种无序的基于 key-value 的数据结构,Go 语言中的 map 是引用类型,必须初始化才能使用. 其中键可以是任何类型,但值必须是可比较的类型(如整数.字符串.布尔 ...

  6. Nginx-负载均衡系列

    综合架构-负载均衡系列 目录 综合架构-负载均衡系列 一个新的开始 一 代理模块 proxy 2.1 概述 2.2 正向代理用户 2.3 反向代理 2.4 反向代理环境准备 2.5 反正代理指令 二 ...

  7. Zabbix与乐维监控对比分析(四)——告警管理篇

    在前面发布的Zabbix与乐维监控对比分析文章中,我们评析了二者在架构与性能.Agent管理.自动发现.权限管理.对象管理等方面的差异.接下来让我们一起看看二者在告警管理方面的差异. 告警管理是所有I ...

  8. 摆脱鼠标系列 - vscode 上一个编辑器 下一个编辑器 Ctrl + h Ctrl + l

    摆脱鼠标系列 - vscode 上一个编辑器 下一个编辑器 Ctrl + H Ctrl + L 为什么 根据 hjkl h是左边的原则 h 左移一位 b 左移一个单词 H 移动到句首 0 是行首 I是 ...

  9. Django使用Bootstrap的经典方法

    前面的话 Bootstrap是简单.灵活的用于搭建WEB页面的HTML.CSS.Javascript的工具集.Bootstrap基于HTML5和CSS3,具有漂亮的设计.友好的学习曲线.卓越的兼容性, ...

  10. 如何在forEach内使用异步调用 async/await

    翻自: How to use async and await in a forEach JS loop? https://learn.coderslang.com/0144-how-to-use-as ...