0

0

Spring Boot中创建非共享(原型)Bean的指南

DDD

DDD

发布时间:2025-10-20 11:15:41

|

561人浏览过

|

来源于php中文网

原创

Spring Boot中创建非共享(原型)Bean的指南

在spring boot应用中,默认情况下,通过`@bean`注解声明的对象是单例的,即所有注入点共享同一个实例。然而,对于`resttemplatebuilder`等有状态对象,这种共享可能导致意外的副作用。本文将详细介绍如何利用`@scope("prototype")`注解来创建非共享的、每次注入都生成新实例的bean,从而有效管理有状态组件,避免潜在的并发问题和状态污染。

理解Spring Bean的默认作用域

Spring框架在管理Bean时,默认采用“单例”(Singleton)作用域。这意味着,当您在一个配置类中使用@Bean注解声明一个方法时,Spring IoC容器只会创建该Bean的一个实例。所有后续对该Bean的注入请求(通过@Autowired等)都将获得并共享这同一个实例。这种设计对于无状态的Bean来说非常高效,因为它减少了对象的创建和垃圾回收的开销。

然而,当Bean本身是有状态的,或者其内部状态在不同使用场景下需要独立维护时,默认的单例作用域就会带来问题。例如,RestTemplateBuilder是一个常见的Spring应用组件,用于构建RestTemplate实例。RestTemplateBuilder是有状态的,如果在构建过程中对其进行配置(如添加拦截器、设置超时等),这些配置会影响到所有使用该单例RestTemplateBuilder实例的地方,可能导致意料之外的副作用和行为冲突。

创建非共享(原型)Bean

为了解决有状态Bean的共享问题,Spring提供了“原型”(Prototype)作用域。当一个Bean被定义为原型作用域时,Spring容器在每次请求该Bean时都会创建一个全新的实例。这确保了每个注入点都拥有一个独立的对象实例,从而避免了状态污染和副作用。

要将一个Bean定义为原型作用域,只需在@Bean注解的同时,添加@Scope("prototype")注解即可。

示例代码

以下是如何在Spring Boot中定义一个原型作用域的Bean的示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;

@Configuration
public class AppConfig {

    /**
     * 定义一个原型作用域的Person Bean。
     * 每次注入或请求该Bean时,Spring都会创建一个新的Person实例。
     */
    @Bean
    @Scope("prototype")
    public Person personPrototype() {
        System.out.println("Creating a new Person prototype instance.");
        return new Person();
    }

    /**
     * 另一种定义原型作用域的方式,使用ConfigurableBeanFactory常量。
     * 这种方式更具类型安全性,推荐使用。
     */
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public MyService myServicePrototype() {
        System.out.println("Creating a new MyService prototype instance.");
        return new MyService();
    }
}

// 示例实体类
class Person {
    private String name;
    // ... getters and setters
}

// 示例服务类
class MyService {
    private String config;
    // ... getters and setters
}

在上面的示例中,personPrototype()方法和myServicePrototype()方法都创建了原型作用域的Bean。每次有其他组件通过@Autowired请求Person或MyService时,Spring容器都会执行相应的@Bean方法,并返回一个新的对象实例。

Build AI
Build AI

为您的业务构建自己的AI应用程序。不需要任何技术技能。

下载

使用ConfigurableBeanFactory常量

为了提高代码的可读性和类型安全性,推荐使用ConfigurableBeanFactory.SCOPE_PROTOTYPE常量来指定原型作用域,而不是直接使用字符串"prototype"。

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
// ... 其他导入

@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public MyService myServicePrototype() {
    return new MyService();
}

原型Bean的生命周期管理

与单例Bean不同,Spring容器对原型Bean的生命周期管理有限。Spring负责创建原型Bean并将其交给客户端,但此后,容器不再跟踪其生命周期。这意味着,对于原型Bean的销毁回调(如@PreDestroy注解或DisposableBean接口),Spring容器不会自动调用。客户端代码需要自行负责原型Bean的清理工作,例如手动释放资源。

何时使用原型作用域

原型作用域主要适用于以下场景:

  1. 有状态的Bean:当Bean内部包含需要在不同使用场景下独立维护的状态时,如RestTemplateBuilder、StringBuilder、Date对象等。
  2. 线程不安全的Bean:如果一个Bean不是线程安全的,并且需要在多线程环境中并发使用,将其定义为原型可以为每个线程提供独立的实例。
  3. 每次请求都需要全新实例的场景:例如,在Web应用中,每个HTTP请求可能需要一个全新的、独立的业务处理对象。

注意事项

  • 性能开销:由于每次请求都会创建新实例,原型Bean的创建和垃圾回收开销会比单例Bean高。因此,不应滥用原型作用域,只在确实需要时使用。
  • 依赖注入:Spring容器在创建原型Bean时,会解析并注入其依赖。但如果原型Bean依赖于一个单例Bean,该单例Bean只会在原型Bean首次创建时注入一次。
  • AOP代理:如果原型Bean需要被AOP代理,Spring会为每个原型实例创建一个独立的代理对象。

总结

Spring Bean的作用域是管理对象生命周期的核心概念。虽然默认的单例作用域在大多数情况下表现良好,但对于有状态或需要独立实例的Bean,如RestTemplateBuilder,理解并正确使用原型(@Scope("prototype"))作用域至关重要。通过为这些特定Bean配置原型作用域,我们可以有效地避免潜在的状态冲突和副作用,确保应用程序的稳定性和可预测性。在决定Bean的作用域时,务必根据其实际需求和特性进行权衡。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

98

2025.08.06

spring boot框架优点
spring boot框架优点

spring boot框架的优点有简化配置、快速开发、内嵌服务器、微服务支持、自动化测试和生态系统支持。本专题为大家提供spring boot相关的文章、下载、课程内容,供大家免费下载体验。

135

2023.09.05

spring框架有哪些
spring框架有哪些

spring框架有Spring Core、Spring MVC、Spring Data、Spring Security、Spring AOP和Spring Boot。详细介绍:1、Spring Core,通过将对象的创建和依赖关系的管理交给容器来实现,从而降低了组件之间的耦合度;2、Spring MVC,提供基于模型-视图-控制器的架构,用于开发灵活和可扩展的Web应用程序等。

384

2023.10.12

Java Spring Boot开发
Java Spring Boot开发

本专题围绕 Java 主流开发框架 Spring Boot 展开,系统讲解依赖注入、配置管理、数据访问、RESTful API、微服务架构与安全认证等核心知识,并通过电商平台、博客系统与企业管理系统等项目实战,帮助学员掌握使用 Spring Boot 快速开发高效、稳定的企业级应用。

61

2025.08.19

Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性
Java Spring Boot 4更新教程_Java Spring Boot 4有哪些新特性

Spring Boot 是一个基于 Spring 框架的 Java 开发框架,它通过 约定优于配置的原则,大幅简化了 Spring 应用的初始搭建、配置和开发过程,让开发者可以快速构建独立的、生产级别的 Spring 应用,无需繁琐的样板配置,通常集成嵌入式服务器(如 Tomcat),提供“开箱即用”的体验,是构建微服务和 Web 应用的流行工具。

8

2025.12.22

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

101

2025.12.24

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1435

2023.10.24

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

248

2023.08.03

vlookup函数使用大全
vlookup函数使用大全

本专题整合了vlookup函数相关 教程,阅读专题下面的文章了解更多详细内容。

28

2025.12.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java 教程
Java 教程

共578课时 | 39.7万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号