@Scope(“prototype“)

@Scope("prototype") 是 Spring 框架中用于定义 Bean 作用域的注解之一,它的主要作用是将一个 Bean 定义成 原型作用域Prototype Scope)。在原型作用域下,每次从 Spring 容器中请求这个 Bean 时,都会创建一个新的实例。


@Scope("prototype") 的作用

  1. 默认作用域:单例(Singleton Scope)
    在 Spring 中,Bean 的默认作用域是单例(@Scope("singleton")),意味着整个 Spring 容器中只会创建一个该 Bean 的实例,无论获取该 Bean 的次数有多少,都会返回同一个实例。

  2. 原型作用域(Prototype Scope)
    如果将 Bean 标记为 @Scope("prototype"),则表示该 Bean 是原型作用域。每次通过 Spring 容器获取这个 Bean 时,都会创建一个全新的实例,这与单例作用域的行为完全不同。


如何使用 @Scope("prototype")

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype") // 标记为原型作用域
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("PrototypeBean instance created!");
    }
}

@Scope("prototype") 的生命周期

与单例作用域的 Bean 不同,原型作用域的 Bean 具有以下特点:

  1. 每次请求都会创建一个新实例

    • 无论通过调用 ApplicationContext#getBean() 方法,还是通过注入方式(例如通过 @Autowired)获取原型作用域的 Bean,每次都会创建一个全新的实例。
  2. 不受 Spring 容器的完全管理

    • Spring 容器只负责创建和返回原型作用域的 Bean,但不会对其进行后续的生命周期管理(例如,不会销毁它)。
    • 开发者需要负责清理(销毁)原型作用域的 Bean(如果需要)。
  3. 适用场景

    • 原型作用域适用于需要「短生命周期」的对象,或者需要生成多个实例的场景,例如:
      • 操作中需要临时创建对象(如一个用户操作的上下文)。
      • 在某些场景中,您需要一个特定的对象,每次使用时都需要是全新的(而不是共享的)。

对比 @Scope("singleton")@Scope("prototype")

特性单例作用域(Singleton)原型作用域(Prototype)
默认值
实例数量Spring 容器中只有一个实例每次请求都会创建一个新实例
实例管理由 Spring 容器全权负责(包括初始化和销毁)仅由 Spring 容器负责创建,不负责销毁
适用场景适用于共享的全局对象(如服务类或工具类等)适用于需要「短生命周期」或需要动态创建的对象

示例代码与行为分析

以下是一个完整示例,演示 @Scope("prototype") 的作用:

PrototypeBean 类
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("PrototypeBean instance created!");
    }
}
SingletonBean 类
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SingletonBean {

    @Autowired
    private PrototypeBean prototypeBean1;

    public void showPrototypeBean() {
        System.out.println("PrototypeBean instance: " + prototypeBean1);
    }
}
主方法
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TestApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext("com.example");

        // 第一次获取 SingletonBean
        SingletonBean singletonBean1 = context.getBean(SingletonBean.class);
        singletonBean1.showPrototypeBean();

        // 第二次获取 SingletonBean
        SingletonBean singletonBean2 = context.getBean(SingletonBean.class);
        singletonBean2.showPrototypeBean();

        // 手动获取 PrototypeBean
        PrototypeBean prototypeBean1 = context.getBean(PrototypeBean.class);
        PrototypeBean prototypeBean2 = context.getBean(PrototypeBean.class);

        System.out.println("PrototypeBean instances comparison: " + (prototypeBean1 == prototypeBean2)); // false
    }
}
输出结果
PrototypeBean instance created!
PrototypeBean instance: com.example.PrototypeBean@1a2b3c4
PrototypeBean instance: com.example.PrototypeBean@1a2b3c4
PrototypeBean instance created!
PrototypeBean instance created!
PrototypeBean instances comparison: false

分析:

  1. PrototypeBean 的实例在 Spring 容器初始化时并未被创建(不同于单例作用域)。
  2. 每次调用 context.getBean(PrototypeBean.class) 时都会创建一个新实例。
  3. 如果将一个原型作用域的 Bean 注入到单例作用域的 Bean 中,Spring 容器只会注入 一个实例(因为依赖注入通常发生在容器启动时),后续不会动态更新。

在原型作用域中动态获取实例

如果您需要在运行时动态获取新的原型实例,可以通过以下方式解决:

  1. 使用 @Lookup 注解
    在单例作用域的 Bean 中通过 @Lookup 动态注入原型实例(如之前的例子)。

  2. 手动调用 ApplicationContext#getBean()
    手动从容器中获取新的原型实例。

  3. 使用 ObjectFactoryProvider
    通过 ObjectFactoryjavax.inject.Provider 提供动态获取实例的能力。

示例(使用 ObjectFactory):

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class SingletonBean {

    @Autowired
    private ObjectFactory<PrototypeBean> prototypeBeanFactory;

    public void showPrototypeBean() {
        PrototypeBean prototypeBean = prototypeBeanFactory.getObject(); // 获取一个新的 PrototypeBean 实例
        System.out.println("PrototypeBean instance: " + prototypeBean);
    }
}

总结

  • @Scope("prototype") 意味着每次请求都会创建一个新的 Bean 实例。
  • 原型作用域适用于需要动态创建、短生命周期的对象。
  • 需要注意的是,Spring 容器不会完全管理原型作用域的 Bean,销毁和清理需要开发者自行处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/955859.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】15.Linux进程概念(4)

文章目录 程序地址空间前景回顾C语言空间布局图&#xff1a;代码1代码2代码3代码4代码5代码6代码7 程序地址空间前景回顾 历史核心问题&#xff1a; pid_t id fork(); if(id 0) else if(id>0) 为什么一个id可以放两个值呢&#xff1f;之前没有仔细讲。 C语言空间布局图&am…

【无法下载github文件】虚拟机下ubuntu无法拉取github文件

修改hosts来进行解决。 步骤一&#xff1a;打开hosts文件 sudo vim /etc/hosts步骤二&#xff1a;查询 github.com的ip地址 https://sites.ipaddress.com/github.com/#ipinfo将github.com的ip地址添加到hosts文件末尾&#xff0c;如下所示。 140.82.114.3 github.com步骤三…

Android BitmapShader实现狙击瞄具十字交叉线准星,Kotlin

Android BitmapShader实现狙击瞄具十字交叉线准星&#xff0c;Kotlin <?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.…

Android系统开发(十):标准协议和通讯的桥梁:探索蓝牙、NFC、WLAN 的工作原理

引言&#xff1a; 现代社会已经是信息互联的世界&#xff0c;各种设备之间的互联互通已经成为了生活的一部分。而在这个过程中&#xff0c;Android 设备与其他硬件之间的通信扮演着至关重要的角色。从蓝牙耳机到 WiFi 路由器&#xff0c;甚至与电话功能的互动&#xff0c;所有…

node中文名的js文件有问题

新版Node无法运行含有中文名的JS文件&#xff0c;具体表现在无报错无反应。如下图&#xff1a; 源码如下&#xff1a; 改成英文的JS文件&#xff0c;则正常&#xff0c;如下图&#xff1a;

BERT与CNN结合实现糖尿病相关医学问题多分类模型

完整源码项目包获取→点击文章末尾名片&#xff01; 使用HuggingFace开发的Transformers库&#xff0c;使用BERT模型实现中文文本分类&#xff08;二分类或多分类&#xff09; 首先直接利用transformer.models.bert.BertForSequenceClassification()实现文本分类 然后手动实现B…

openharmony应用开发快速入门

开发准备 本文档适用于OpenHarmony应用开发的初学者。通过构建一个简单的具有页面跳转/返回功能的应用&#xff08;如下图所示&#xff09;&#xff0c;快速了解工程目录的主要文件&#xff0c;熟悉OpenHarmony应用开发流程。 在开始之前&#xff0c;您需要了解有关OpenHarmon…

RabbitMQ---TTL与死信

&#xff08;一&#xff09;TTL 1.TTL概念 TTL又叫过期时间 RabbitMQ可以对队列和消息设置TTL&#xff0c;当消息到达过期时间还没有被消费时就会自动删除 注&#xff1a;这里我们说的对队列设置TTL,是对队列上的消息设置TTL并不是对队列本身&#xff0c;不是说队列过期时间…

51.WPF应用加图标指南 C#例子 WPF例子

完整步骤&#xff1a; 先使用文心一言生成一个图标如左边使用Windows图片编辑器编辑&#xff0c;去除背景使用正方形&#xff0c;放大图片使图标铺满图片使用格式工程转换为ico格式&#xff0c;分辨率为最大 在资源管理器中右键项目添加ico类型图片到项目里图片属性设置为始终…

多语言插件i18n Ally的使用

先展示一下效果 1.第一步首先在vscode下载插件 2.第二步在 setting.json 里面配置 要区分文件是js&#xff0c;ts或json结尾 以zh.ts和en.ts结尾的用这个 { "i18n-ally.localesPaths": ["src/locales"],"i18n-ally.keystyle": "nested"…

蓝桥杯备考:堆和priority queue(优先级队列)

堆的定义 heap堆是一种特殊的完全二叉树&#xff0c;对于树中的每个结点&#xff0c;如果该结点的权值大于等于孩子结点的权值&#xff0c;就称它为大根堆&#xff0c;小于等于就叫小根堆&#xff0c;如果是大根堆&#xff0c;每个子树也是符合大根堆的特征的&#xff0c;如果是…

【人工智能】:搭建本地AI服务——Ollama、LobeChat和Go语言的全方位实践指南

前言 随着自然语言处理&#xff08;NLP&#xff09;技术的快速发展&#xff0c;越来越多的企业和个人开发者寻求在本地环境中运行大型语言模型&#xff08;LLM&#xff09;&#xff0c;以确保数据隐私和提高响应速度。Ollama 作为一个强大的本地运行框架&#xff0c;支持多种先…

Java锁 从乐观锁和悲观锁开始讲 面试复盘

目录 面试复盘 Java 中的锁 大全 悲观锁 专业解释 自我理解 乐观锁 专业解释 自我理解 悲观锁的调用 乐观锁的调用 synchronized和 ReentrantLock的区别 相同点 区别 详细对比 总结 面试复盘 Java 中的锁 大全 悲观锁 专业解释 适合写操作多的场景 先加锁可以…

OpenVela——专为AIoT领域打造的开源操作系统

目录 一、系统背景与开源 1.1. 起源 1.2. 开源 二、系统特点 2.1. 轻量化 2.2. 标准兼容性 2.3. 安全性 2.4. 高度可扩展性 三、技术支持与功能 3.1. 架构支持 3.2. 异构计算支持 3.3. 全面的连接套件 3.4. 开发者工具 四、应用场景与优势 4.1. 应用场景 4.2. …

使用 Java 实现基于 DFA 算法的敏感词检测

使用 Java 实现基于 DFA 算法的敏感词检测 1. 引言 敏感词检测在内容审核、信息过滤等领域有着广泛的应用。本文将介绍如何使用 DFA&#xff08;Deterministic Finite Automaton&#xff0c;确定有限状态自动机&#xff09; 算法&#xff0c;在 Java 中实现高效的敏感词检测。…

单片机存储器和C程序编译过程

1、 单片机存储器 只读存储器不是并列关系&#xff0c;是从ROM发展到FLASH的过程 RAM ROM 随机存储器 只读存储器 CPU直接存储和访问 只读可访问不可写 临时存数据&#xff0c;存的是CPU正在使用的数据 永久存数据&#xff0c;存的是操作系统启动程序或指令 断电易失 …

UDP报文格式

UDP是传输层的一个重要协议&#xff0c;他的特性有面向数据报、无连接、不可靠传输、全双工。 下面是UDP报文格式&#xff1a; 1&#xff0c;报头 UDP的报头长度位8个字节&#xff0c;包含源端口、目的端口、长度和校验和&#xff0c;其中每个属性均为两个字节。报头格式为二…

2024年我的技术成长之路

2024年我的技术成长之路 大家好&#xff0c;我是小寒。又到年底了&#xff0c;一年过得真快啊&#xff01;趁着这次活动的机会&#xff0c;和大家聊聊我这一年在技术上的收获和踩过的坑。 说实话&#xff0c;今年工作特别忙&#xff0c;写博客的时间比去年少了不少。不过还是…

HTML5+Canvas实现的鼠标跟随自定义发光线条源码

源码介绍 HTML5Canvas实现的鼠标跟随自定义发光线条特效源码非常炫酷&#xff0c;在黑色的背景中&#xff0c;鼠标滑过即产生彩色变换的发光线条效果&#xff0c;且线条周围散发出火花飞射四溅的粒子光点特效。 效果预览 源码如下 <!DOCTYPE html PUBLIC "-//W3C//D…

爬虫第二篇

太聪明了怎么办&#xff1f;那就&#xff0c;给脑子灌点水&#xff01;&#xff01; 本篇文章我们来简单讲一下如何爬取mv,也就是歌曲视频&#xff0c;那么我们进入正题。 由于上次拿网易云开了刀&#xff0c;那么这次我们拿酷狗开刀。 还是进入上次讲过的页面 注意&#xff…