Spring Bean的作用域以及注解使用

article/2025/9/22 22:00:13

点击上方 Java学习之道,选择 设为星标

每天12点,干货准时奉上!

Spring Bean的作用域

Spring Bean 的作用域即为对象的作用范围。Spring Bean的作用域由配置项 scope 来限定。

Scope配置项

作用域限定了 Spring Bean 的作用范围,在 Spring 配置文件定义 Bean 时,通过声明 scope 配置项,可以灵活定义 Bean 的作用范围。

想要容器创建的 bean 为单例模式,就设置 Scope 为 singleton;想要每次创建的 bean 都是不同的对象则使用 prototype

六大作用域

官方文档给出的bean作用域的简单介绍。文档的表格写着是六个作用域,但是很多时候都会被认为只有五个作用域。因为 applicationwebsocket 的作用差不多。所以会被认为是一个。

范围描述
singleton(默认)将每个Spring IoC容器的单个 bean 定义范围限定为单个对象实例。
prototype将单个 bean 定义的作用域限定为任意数量的对象实例。
request将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有一个自己的 bean 实例,它是在单个 bean 定义的后面创建的。仅在可感知网络的 Spring 上下文中有效 ApplicationContext
session将单个 bean 定义的范围限定为 HTTP 的生命周期 Session。仅在可感知网络的 Spring 上下文中有效 ApplicationContext
application将单个 bean 定义的作用域限定为的生命周期 ServletContext。仅在可感知网络的Spring上下文中有效 ApplicationContext
websocket将单个 bean 定义的作用域限定为的生命周期 WebSocket。仅在可感知网络的Spring上下文中有效 ApplicationContext

本文重点放在 singleton 和 prototype ,后面四个是对于WebMVC而言的,这里暂不进行详细阐述。

单例作用域

先来说说第一个单例范围,单例范围即无论使用多少个 Dao 去获取 bean ,每次获取到的都是一个相同的 bean对象。「singleton」 这与我们所说的单例模式基本是相同的,singleton 也是默认的作用域,如果没用指定 bean 对象的作用域则在整个上下文环境中通过 Spring IOC 获取到的 bean 都是同一个实例。

配置 bean 为 singleton 作用域代码:

<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

接下来定义一个POJO类 -- User来演示 scope 属性对实例的影响。

public class User {private String name;private int age;public User() {}public User(String name, int age) {this.name = name;this.age = age;}/*toString和getter/setter*/@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

再显示的把该 bean 的作用域设置为 singleton。

<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd "><bean id="user" class="com.javastudyway.pojo.User" p:name="Java学习之道" p:age="4" scope="singleton"/></beans>

最后就是测试类了:

import com.javastudyway.pojo.Student;
import com.javastudyway.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {@Testpublic void testSingleton(){ApplicationContext context = new ClassPathXmlApplicationContext("userbean.xml");User user1 = context.getBean("user",User.class);User user2 = context.getBean("user",User.class);System.out.println(user1 == user2);}
}

测试结果如下:从比较结果可以看出,程序两次从 IOC 容器中获取的 User 实例「地址比较结果相同」,说明 IOC 容器返回的是「同一个实例」

原型作用域

与 singleton 刚好相反,prototype,是程序每次从 IOC 容器获取的 Bean 都是一个新的实例。这次把 bean 的配置修改成 「prototype」,再进行测试。

<bean id="user" class="com.javastudyway.pojo.User" p:name="Java学习之道" p:age="4" scope="prototype"/>

在测试类中增加一个测试方法:

@Test
public void testPrototype(){ApplicationContext context = new ClassPathXmlApplicationContext("userbean.xml");User user1 = context.getBean("user", User.class);User user2 = context.getBean("user", User.class);System.out.println("两次对象地址比较结果为:" + (user1 == user2));System.out.println("user1 的hasCode为:" + user1.hashCode());System.out.println("user2 的hasCode为:" + user2.hashCode());
}

测试结果为:可以看到,程序两次从 IOC 容器中获取的 user1 和 user2 实例的 hashCode 不相同,说明 User 添加 prototype 作用域后,IOC 容器每次返回的都是一个新的实例。

对于作用域使用场景的总结:

有状态的bean应该使用prototype作用域;

对无状态的bean则应该使用singleton作用域。

使用注解声明bean的作用域

大多数时候,我们都不想很麻烦的去修改 applicationContext.xml ,因为修改文件总是烦躁得让人抗拒。

所以我们可以使用注解来配置 bean 的作用范围。具体步骤为

  • 使用 「@Component」 注解将 POJO 类声明为一个 bean;

  • 使用 「@Scope」 注解声明 bean 的作用域;

  • 修改 「applicationContext.xml」 开启扫描 POJO 包中的所有类的注解。

修改POJO类

在 POJO 类上增加 @Component,让 Spring 将 User 视为一个 bean。

在 POJO 类上增加 @Scope 注解,标识 该 bean 的作用域为 singleton。

package com.javastudyway.pojo;import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("user")
@Scope("singleton")
public class User {private String name;private int age;public User() {}public User(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

开启注解扫描

增加完注解后我们只需要对 applicationContext.xml 这个 Spring 的配置文件做上一小部分修改,即可实现注解开发了。

开启 com.javastudyway.pojo 包中的所有类的注解扫描。

<?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:context="http://www.springframework.org/schema/context"xmlns:p="http://www.springframework.org/schema/p"xmlns:c="http://www.springframework.org/schema/c"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!-- 开启注解扫描 --><context:component-scan base-package="com.javastudyway.pojo"/></beans>

测试

对 POJO 类加上注解和开启注解扫描后,我们就可以通过简单的注解来设置 bean 的作用域而不再需要去配置文件中慢慢修找修改了。用刚刚 测试原型作用域的方法 来测试用注解修改成 singleton 的 bean。

结果从原来的 「false,hashCode 不相等」变成了 「true,hashCode 相等」了。

-- END --

 | 更多精彩文章 -


  • [漫画]献给写代码把自己蠢乐的自己

  • Redis内存爆满了怎么办?

  • (修订版)Spring对象如何创建与管理,又如何使用巧妙的方法注入属性呢?

  • Nginx是如何快到让人吃惊又稳定的?

  • 买西瓜懂得了如何教女朋友编程

《Java学习-进阶手册》

公众号后台回复「手册」获取资料

▽加我微信,交个朋友长按/扫码添加↑↑↑


http://chatgpt.dhexx.cn/article/3vvlM5GK.shtml

相关文章

JAVA bean的作用域

1、Bean的5种作用域 &#xff08;1&#xff09;singleton&#xff1a;单例模式&#xff0c;Spring IoC容器中只会存在一个共享的Bean实例&#xff0c;无论有多少个Bean引用它&#xff0c;始终指向同一对象Singleton作用域是Spring中的缺省作用域&#xff0c;也可以显示的将Bean…

Bean 作用域和生命周期

文章目录 引入 Lombok1. Bean 的作用域问题2. 作用域定义2.1 作用域类型2.2 Bean 作用域的设置 3. Bean 的生命周期3.1 执行流程:3.2 **代码示例:** 4.Spring 生命周期 Spring 容器是用来存储和读取 Bean 的 , 因此 Bean 是 Spring 中最核心的操作资源. 引入 Lombok 编写代码过…

【Spring6】| Bean的作用域

目录 一&#xff1a;Bean的作用域 1. singleton&#xff08;单例&#xff09; 2. prototype&#xff08;多例&#xff09; 3. 其它scope 4. 自定义scop&#xff08;了解&#xff09; tips&#xff1a;首先给大家推荐两款好用的免费软件&#xff1a;动图抓取软件&#xff1…

Spring Bean的作用域及生命周期

目录 前言&#xff1a; Bean的作用域&#xff08;Scope&#xff09; 单例模式 原型模式&#xff08;多例作用域&#xff09; 请求作用域&#xff08;request&#xff09; 会话作用域 全局作用域 网络长连接 Spring执行流程 Bean的生命周期 测试 小结&#xff1a; 前…

Spring中Bean的作用域问题

文章目录 一、通过案例来简单体会一下Bean的作用域问题二、作用域定义三、Bean的作用域分类singletonprototyperequestsessionapplication&#xff08;了解&#xff09;singleton&#xff08;单例作用域&#xff09; 和 application &#xff08;全局作用域&#xff09;的区别w…

面试:Bean 作用域是什么?它有几种类型?

Spring 框架作为一个管理 Bean 的 IoC 容器&#xff0c;那么 Bean 自然是 Spring 中的重要资源了&#xff0c;那 Bean 的作用域是什么意思&#xff1f;又有几种类型呢&#xff1f;接下来我们一起来看。 PS&#xff1a;Java 中的公共类可称之为 Bean 或 Java Bean。 1、作用域…

Spring系列8:bean的作用域

本文内容 bean定义信息的意义介绍6种bean的作用域 bean定义信息的意义 Spring中区分下类、类定义信息&#xff0c;类实例对象的概念&#xff1f;不容易理解&#xff0c;以餐馆中点炒饭为例。 类&#xff1a; 相当于你看到菜单上炒饭这个菜品&#xff0c;有这个菜。 类定义…

【Java第34期】:Bean的六种作用域

作者&#xff1a;有只小猪飞走啦 博客地址&#xff1a;https://blog.csdn.net/m0_62262008?typeblog 内容&#xff1a;介绍Bean的六种作用域的效果以及适用场景 文章目录 前言一&#xff0c;作用域定义以及Bean的六种作用域是什么&#xff1f;二&#xff0c;singleton&#…

Bean的六种作用域

什么是Bean的作用域呢? 这里的"作用域"还和Java中的类级,方法级等这几个作用域概念不太一样,我自己的一个理解是:在Spring执行的这段时间中,Bean的作用域就只有单例和多例这两种,在执行respect这段时间之中,就有它自己的作用域,而到了session中又有它自己的作用域,…

Spring Bean的作用域

在Spring中&#xff0c;bean作用域用于确定哪种类型的bean实例应该从Spring容器中返回给调用者。 目前Spring Bean的作用域或者说范围主要有五种。 作用域描述singleton在spring IoC容器仅存在一个Bean实例&#xff0c;Bean以单例方式存在&#xff0c;bean作用域范围的默认值…

设计原则-依赖倒置

名称&#xff1a;依赖倒置原则&#xff08;Dependence Inversion Principle&#xff09; 定义&#xff1a;程序要依赖于抽象接口&#xff0c;不要依赖于具体实现。依赖倒置原则的中心思想是面向接口编程。 高层模块不应依赖于低层模块&#xff0c;二者都应该依赖于抽象抽象不…

C++之依赖倒置原则

C之依赖倒置原则 1. 依赖于具体抽象&#xff08;接口&#xff09;&#xff0c;不依赖于具体的实现&#xff0c;也就是针对接口编程。 2. 实现高层业务和实现层、实现层和实现层之间的解耦合&#xff1b; 实例&#xff1a; 电脑框架和电脑内部的配件产品&#xff08;或提供配…

【软件架构设计原则】开闭原则和依赖倒置原则

文章目录 软件架构设计原则开闭原则依赖倒置原则最后 软件架构设计原则 本文通过实例来讲解 开闭原则依赖导致原则 开闭原则 开闭原则&#xff08;Open-Close Principle&#xff0c;OCP&#xff09;是指一个软件实体&#xff08;如类、模块和函数&#xff09;应该对扩展开放…

java 依赖倒置_Java设计原则—依赖倒置原则(转)

依赖倒置原则(Dependence Inversion Principle&#xff0c;DIP)的原始定义&#xff1a; 高层模块不应该依赖底层模块&#xff0c;两者都应该依赖其抽象&#xff1b; 抽象不应该依赖细节&#xff1b; 细节应该依赖抽象。 依赖倒置原则在Java语言中的表现是&#xff1a; 模块间的…

设计模式 依赖倒置原则

文章目录 依赖倒置原则依赖倒置原则实战使用依赖倒置原则进行改变案例中两种方式的类图 依赖倒置原则 定义: 程序要依赖于抽象接口, 不要依赖于具体实现, 对抽象进行编程, 而不是对实现进行编程, 降低了客户与实现模块的耦合. 高层模块不应该依赖底层模块, 都应该依赖抽象(接口…

依赖倒置原则应用-司机开车案例

依赖倒置原则 依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口&#xff0c;不要依赖于具体实现。简单的说就是要求对抽象进行编程&#xff0c;不要对实现进行编程&#xff0c;这样就降低了客户与实现模块间的耦合。 依赖倒置原则三层含义&#xff1a; …

4.3 依赖倒置原则

一. 依赖倒置原则的定义 1.核心思想 依赖倒置原则&#xff08;Dependence Inversion Principle&#xff0c;DIP&#xff09; *1.高层模块 不应该依赖 低层模块, 二者都应该依赖其抽象; *2.抽象 不应该依赖 细节, 细节 应该依赖 抽象; 接口和抽象类价值在于设计; *3.依赖倒…

C# 依赖倒置原则(DIP)

目录 一&#xff0c;引子 1.1 传统的程序架构 1.2 依赖倒置 1.3 依赖倒置的作用 二&#xff0c;依赖注入 一&#xff0c;引子 1.1 传统的程序架构 在程序执行过程中&#xff0c;传统的程序架构如图&#xff1a; 可以看到&#xff0c;在传统的三层架构中&#xff0c;层与…

设计模式-依赖倒置原则

依赖倒置原则 1 依赖倒置原则的定义 依赖倒置原则&#xff08;Dependence Inversion Principle,DIP&#xff09;这个名字看着有点别扭&#xff0c;“依赖”还“倒置”&#xff0c;这到底是什么意思&#xff1f;依赖倒置原则的原始定义是&#xff1a; High level modules shou…

C++ 依赖倒置原则

.依赖倒置原则 定义 高层模块不应该依赖于底层模块&#xff0c;而应该依赖于抽象。抽象不应依赖于细节&#xff0c;细节应依赖于抽象。解决的问题 类A直接依赖类B&#xff0c;假如要将类A改为依赖类C&#xff0c;则必须通过修改类A的代码来达成。这种场景下&#xff0c;类A一般…