Spring系统学习 - Bean的作用域

bean作用域介绍

Spring框架提供了不同的作用域来管理Bean的生命周期和可见性,这对于控制不同类型的组件和处理并发请求尤其重要。

  • singleton(默认):

    • 每个Spring IoC容器只有一个bean实例。
    • 当容器创建bean后,它会被缓存起来,后续请求将返回同一个实例。
    • 这是默认的作用域,适用于无状态的服务层bean。
  • prototype:

    • 每次请求都会创建一个新的bean实例。
    • 每当客户端请求该bean时,Spring容器都会创建一个新的实例。
    • 这对于那些需要保持独立状态的bean特别有用,比如基于注解的控制器。
  • request:

    • 每个HTTP请求都有其自己的bean实例。
    • 主要用于Web应用,确保每个HTTP请求都有一个新的bean实例。
    • 这对于有状态的会话bean特别有用。
  • session:

    • 在同一个HTTP Session中,每个Session拥有一个bean实例。
    • 这意味着在用户会话期间,bean实例是共享的。
    • 对于需要在整个会话期间保存状态的bean,这是理想的选择。
  • global-session:

    • 类似于session作用域,但专门用于portlet应用中的全局会话。
    • 在portlet应用中,全局会话是跨所有portlet的会话范围。
  • application:

    • 这个作用域在Web应用中提供一个bean实例,类似于Servlet的application作用域。
    • 该bean在整个Web应用的生命周期内存在,即从应用启动到停止。

除了这些内置作用域,Spring还允许你定义自定义作用域,这通常通过实现org.springframework.beans.factory.config.Scope接口来完成。自定义作用域可以让你根据特定的应用需求来管理bean的生命周期。

常用的

取值 含义 创建对象的时机
singleton(默认) 在IOC容器中,这个bean的对象始终为单实例 IOC容器初始化时
prototype 这个bean在IOC容器中有多个实例 获取bean时

案例演示

java 复制代码
public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer age;
    public User() {
        System.out.println("生命周期:1、创建对象");
    }
    public User(Integer id, String username, String password, Integer age) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.age = age;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        System.out.println("生命周期:2、依赖注入");
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void initMethod(){
        System.out.println("生命周期:3、初始化");
    }
    public void destroyMethod(){
        System.out.println("生命周期:5、销毁");
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }

}

我们创建一个spring-scope.xml演示作用域

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.xsd">


    <!-- scope属性:取值singleton(默认值),bean在IOC容器中只有一个实例,IOC容器初始化时创建
对象 -->
    <!-- scope属性:取值prototype,bean在IOC容器中可以有多个实例,getBean()时创建对象 -->

    <bean id="studentOne" class="com.miaow.spring.bean.Student" scope="prototype">
        <property name="id" value="1"></property>
        <property name="name" value="miaow"></property>
        <property name="address" value="湖南娄底"></property>
        <property name="birthday" value="1999"></property>
        <property name="email" value="2958467385@qq.com"></property>
        <property name="phone" value="15975145237"></property>
        <property name="school" value="知行合一"></property>
        <property name="sex">
            <value>男</value>
        </property>

    </bean>
</beans>

Java测试代码

java 复制代码
@Test
public void ScopeTest(){
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-scope.xml");
        Student student = (Student) context.getBean("studentOne");
        Student student1 = (Student) context.getBean("studentOne");

        System.out.println(student == student1);
}

在上述代码中,我们需要注意的是,xml配置文件中的singleton和prototype,当我们配置singleton的时候你试一下结果如何,我给出prototype的时候的结果如下图所示:

  • 注意线程安全性 :如果Bean是有状态的,并且在多线程环境中使用,需要确保Bean的线程安全性。在多线程环境中,最好使用原型作用域或每次请求创建新的Bean实例。

  • 注意内存消耗 :使用原型作用域时,需要注意内存消耗。如果原型Bean被频繁创建,可能会导致内存占用过高。在这种情况下,可以考虑使用对象池或其他缓存机制来管理Bean的创建和销毁。

  • 注意作用域的选择:根据应用程序的需求,选择适当的作用域。如果Bean的状态不会改变,并且需要在整个应用程序中共享,可以使用单例作用域。如果需要每次请求或会话创建新的实例,可以使用请求或会话作用域

相关推荐
Mr_Macallon26 分钟前
C++回顾(基础)(01)
c语言·开发语言·c++·学习
Sweet锦30 分钟前
不调 Python,不装向量库:我用纯 Java 写了一套以图搜图引擎
java·人工智能·开源·图搜索
如意猴1 小时前
【C++】007 C/C++ 内存管理机制、malloc与new的区别及模板初阶
java·c++·算法
可乐鸡翅yeah_1 小时前
HLS 分片过期清理,直播旧 TS 分片磁盘爆满问题处理
java·后端·spring·m3u8·m3u8在线·音视频在线播放
sunoo-2291 小时前
【ARM嵌入式学习笔记第十天】i.MX6ULL eLCDIF控制器驱动RGB LCD全解析(硬件原理+寄存器配置+裸机代码)
arm开发·笔记·学习
专业程序开发源2 小时前
SSM校园拍摄交流服务平台36936-计算机课程设计、毕业设计
java·spring boot·后端·python·elasticsearch·php·课程设计
用户094248568032 小时前
第23章:OpenJDK逃逸分析、标量替换与锁优化
java·jvm
wuminyu2 小时前
LockStack在虚拟线程Mount和Unmount拷贝过程剖析
java·linux·c语言·jvm·c++
樱花落木兰2 小时前
分布式登录实战:Session 会话共享改造,Redis 存储用户登录状态
java·javascript·数据库·redis·分布式·缓存
HAHAXX82 小时前
电商RPA批量上架通用方案:一套流程如何同时跑通拼多多、抖店、淘宝和跨境平台
java·运维·rpa