Spring Bean的Scope作用域详解

 更新时间:2025年01月06日 09:59:06   作者:catoop  
本文介绍了Spring框架中的BeanScope(作用域),包括Singleton(单例)和Prototype(原型)两种常见作用域的定义、生命周期和适用场景

Spring Bean的Scope作用域

Spring框架中的Bean Scope(作用域)用于控制Bean的生命周期和可见性。

Spring提供了多种作用域,每种作用域决定了Bean在应用中的创建和管理方式。

以下是Spring中最常用的作用域及其特点:

Scope作用域类型

1. Singleton(单例)

  • 默认作用域: 如果没有显式指定作用域,默认就是Singleton。
  • 生命周期: 在整个应用中,只有一个实例。这个实例在Spring容器启动时创建,并且在整个应用运行期间一直存在。
  • 适用场景: 适用于无状态的Bean,如服务层和DAO层的Bean。
 @Component
 @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
 public class MySingletonComponent {
     // ...
 }

2. Prototype(原型)

  • 生命周期: 每次请求都会创建一个新的实例。Spring容器在创建原型Bean后,就不再管理其生命周期。
  • 适用场景: 适用于有状态的Bean,如需要每个请求都独立处理的Bean。
 @Component
 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
 public class MyPrototypeComponent {
     // ...
 }

在Spring框架中,使用@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)修饰的@Component表示该组件是一个原型(Prototype)作用域的bean。

这意味着每次通过Spring容器请求这个bean时,都会创建一个新的实例。

与单例(Singleton)作用域的bean不同,原型作用域的bean不会被缓存,每次请求都会返回一个新的实例。

生命周期

每次请求都创建新实例

  • 每次调用context.getBean(MyPrototypeComponent.class)时,都会创建一个新的MyPrototypeComponent实例。
  • 这意味着每个请求之间是隔离的,每个实例都有独立的状态。

生命周期管理

  • 原型作用域的bean的生命周期由创建它的客户端代码负责管理。Spring容器只负责初始化和装配bean,一旦bean被创建并返回给客户端代码,容器就不再管理其生命周期。
  • 容器不会调用销毁方法(如@PreDestroy注解的方法)来清理资源,因为容器不知道何时应该销毁这些bean,这也反向说明了原型Bean被Spring创建后就不在管理其生命周期了。

在Spring框架中,当一个Bean的作用域被设置为SCOPE_PROTOTYPE时,这个Bean在容器启动时不会被自动实例化。相反,每次通过Spring容器请求这个Bean时,才会创建一个新的实例。

关键总结

Singleton作用域

  • 默认作用域。
  • 在容器启动时被实例化一次。
  • 整个应用生命周期内只存在一个实例。

Prototype作用域

  • 每次请求时都会创建一个新的实例(也是每次请时才会创建,一个被定义为该作用域的类如果没有在任何地方使用它,那么你可以认为它和一个普通的Java类没有区别)。
  • 请求的方式包括注入该Bean到其他Bean里,每注入一个地方都是一个独立的Bean。或者使用 context.getBean 方式获取Bean的时候。
  • 容器启动时不会自动实例化。
  • 容器在创建Bean后不再管理其生命周期。
  • 特别适合那种需要注入Spring中其他类的Java类,但是这个类又是在某些场景需要的时候才需要实例化的场景,例如实现 Runnable 接口的线程任务类。

示例:

@Data
@Accessors(chain = true)
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Task implements Runnable {

    private TaskInfo taskInfo;

    // 注入对象
    @Autowired
    private TaskService taskService;

    @Override
    public void run() {
        taskService.process(taskInfo);
    }
}
// 调用示例代码
ApplicationContext context = xxx;
ExecutorService executor = xxx;
TaskInfo taskInfo = xxx;
// 这里每次getBean获取的Task对象都是一个新的实例
Task task = context.getBean(Task.class).setTaskInfo(taskInfo);
executor.execute(task);

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 一文详解如何在控制台显示MyBatis的SQL语句

    一文详解如何在控制台显示MyBatis的SQL语句

    这篇文章主要为大家介绍了如何在控制台显示MyBatis的SQL语句实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 解析Java 中for循环和foreach循环哪个更快

    解析Java 中for循环和foreach循环哪个更快

    这篇文章主要介绍了Java中for循环和foreach循环哪个更快示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • JDBC示例代码

    JDBC示例代码

    本教程提供了如何创建一个简单的JDBC应用程序的示例。演示如何打开一个数据库连接,执行SQL查询,并显示结果
    2014-03-03
  • 详解关于IntelliJ IDEA中Schedule for Addition 的问题

    详解关于IntelliJ IDEA中Schedule for Addition 的问题

    本篇文章主要介绍了详解关于 IntelliJ IDEA 中 Schedule for Addition 的问题,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-12-12
  • 这么设置IDEA中的Maven,再也不用担心依赖下载失败了

    这么设置IDEA中的Maven,再也不用担心依赖下载失败了

    今天给大家带来一个IDEA中Maven设置的小技巧.这个技巧可以说非常有用,学会设置之后,再也不用担心maven依赖下载变慢的问题,需要的朋友可以参考下
    2021-05-05
  • mybatis resultType自带数据类型别名解读

    mybatis resultType自带数据类型别名解读

    MyBatis为了简化开发,通过org.apache.ibatis.type.TypeAliasRegistry为常见类定义了别名,这些别名包括基本数据类型及其数组、集合类型等,如string对应java.lang.String,int对应java.lang.Integer等,此外,还有特殊前缀的别名如_int对应int类型
    2024-10-10
  • Java中JSON字符串进行各种转换的方法小结

    Java中JSON字符串进行各种转换的方法小结

    Gson和Hutool的JSONUtil都是常用的用于处理JSON数据的工具库,它们提供了简单易用的API来进行JSON字符串的解析、转换和操作,下面就跟随小编一起学习一下如果使用他们实现JSON字符串的各种转换吧
    2024-01-01
  • MyBatis学习教程之开发Dao的方法教程

    MyBatis学习教程之开发Dao的方法教程

    这篇文章主要给大家介绍了关于MyBatis开发Dao的相关资料,使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。文中通过示例代码介绍的非常详细,需要的朋友们下面来一起看看吧。
    2017-07-07
  • Java版水果管理系统源码

    Java版水果管理系统源码

    这篇文章主要为大家详细介绍了Java版水果管理系统源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • Spring Boot Jwts Token生成方法示例

    Spring Boot Jwts Token生成方法示例

    这篇文章主要为大家介绍了Spring Boot Jwts Token生成方法示例,非适合java初学者,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09

最新评论