Spring中动态注册和销毁对象

1. 使用说明

        通常我们项目中想要往spring容器中注入一个bean可以在项目初始化的时候结合@Bean注解实现。但是该方法适合项目初始化时候使用,如果后续想要继续注入对象则无可奈何。本文主要描述一种在后续往spring容器注入bean的方法。

2. 实现

2.1 说明

2.1.1 注册bean

  • 定义BeanDefinition,注册类定义到factory中
  • 创建对象,注册实例到fatory中

2.1.2 销毁bean

  • 判断是否有类定义。有,则移除BeanDefinition
  • 判断是否有对象。有,则从容器中去除

2.2 代码

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

/**
 * @author pp_lan
 * @date 2024/1/17
 */
@Component
public class SpringUtils {

    @Autowired
    private ApplicationContext context;

    private DefaultListableBeanFactory factory;

    @PostConstruct
    public void init() {
        factory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
    }

    /**
     * 注册对象
     *
     * @param beanName
     * @param object
     */
    public void registerBean(String beanName, Object object) {
        // 添加类定义
        factory.registerBeanDefinition(beanName, new RootBeanDefinition(object.getClass()));
        // 添加类实例
        factory.registerSingleton(beanName, object);
    }

    /**
     * 删除对象
     *
     * @param beanName
     */
    public void removeBean(String beanName) {
        List<String> beanDefinitionList = Arrays.asList(factory.getBeanDefinitionNames());
        if (beanDefinitionList.contains(beanName)) {
            factory.destroySingleton(beanName);
        }

        for (Iterator<String> it = factory.getBeanNamesIterator();it.hasNext();) {
            String next = it.next();
            if (next.equals(beanName)) {
                factory.removeBeanDefinition(beanName);
                return;
            }
        }
    }

    /**
     * 获取bean
     *
     * @param clazz
     * @return
     * @param <T>
     */
    public <T> T getBean(String name, Class<T> clazz) {
        for(Iterator<String> it = factory.getBeanNamesIterator();it.hasNext();) {
            String next = it.next();
            if (next.equals(name)) {
                return this.context.getBean(name, clazz);
            }
        }

        return null;
    }
}

2.3 测试代码

 @RequestMapping("/addUser")
 public Response add(String userId) {
        User user = new User(userId, "zhang", "小张");
        springUtils.removeBean("user");
        springUtils.registerBean("user", user);
        User zhang = springUtils.getBean("user", User.class);
        return Response.ok(zhang);
 }

 @RequestMapping("/get")
 public Response get() {
        return Response.ok(springUtils.getBean("user", User.class));
 }

3. 运行

3.1 初次运行

3.2 注册bean

使用addUser注册后,使用get方法获取容器内中的user对象,结果如下:

3.3 再次注册,覆盖对象

销毁已存在的对象,重新注册对象。使用get方法获取容器内中的user对象,结果如下:

4. 总结

        通过removeBean方法和registerBean结合,可以达到spring容器内对象的销毁、注册、替换等目的。

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

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

相关文章

Page268~270 11.3.4 wxWidgets项目配置

项目w28_gui的项目配置&#xff1a; 一&#xff0c;编译选项&#xff0c; -pipe -mthreads [[if (GetCompilerFactory().GetCompilerVersionString(_T("gcc")) > _T("4.8.0")) print(_T("-Wno-unused-local-typedefs"));]] 1, -pipe&#…

spark dateformat源码排错

背景 有一个任务 yyyy写成了YYYY&#xff0c;导致年份不对触发告警 select from_unixtime(unix_timestamp(),YYYY-MM-dd HH:mm:ss) 第一时间用spark dateformat搜索下看看官网&#xff0c;发现spark 官网也没有描述YYYY的信息 Datetime patterns - Spark 3.5.0 Documentati…

【计算机组成与体系结构Ⅱ】Cache性能分析(实验)

实验6&#xff1a;Cache性能分析 一、实验目的 1&#xff1a;加深对 Cache 的基本概念、基本组织结构以及基本工作原理的理解。 2&#xff1a;掌握 Cache 容量、相联度、块大小对 Cache 性能的影响。 3&#xff1a;掌握降低 Cache 不命中率的各种方法以及这些方法对提高 Ca…

Springboot智慧校园电子班牌统一管理平台源码

借助AIoT智能物联、云计算技术打造智慧绿色校园&#xff0c;助力实现校园教务管理、教师管理、学籍管理、考勤、信息发布、班级文明建设、校园风采、家校互通等场景功能&#xff0c;打造安全、便捷、绿色的智慧校园。 前后端分离架构 1、使用springbootvue2 2、数据库&#xff…

Day31 46全排列 47全排列II 回溯去重tips 51N皇后 37解数独

46 全排列 给定一个 没有重复 数字的序列&#xff0c;返回其所有可能的全排列。 示例: 输入: [1,2,3]输出: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ] 排列问题与组合问题的不同之处就在于&#xff0c;没有startIndex&#xff0c;同时需要设置一个used数组…

剩余电流继电器装在哪里?电工必备知识

可实时监测和显示TN-S、TT系统配电线路的剩余电流&#xff1b; 每只剩余电流监测仪最多可监测16个回路的剩余电流&#xff0c;剩余电流监测范围为1mA-30A&#xff1b; 每路剩余电流监测均可设置报警值&#xff0c;报警值的设置范围为5mA-30A。每路剩余电流监测可设置为超值…

Docker(一)简介和基本概念

一、简介 本章将带领你进入 Docker 的世界。 什么是 Docker&#xff1f; 用它会带来什么样的好处&#xff1f; 好吧&#xff0c;让我们带着问题开始这神奇之旅。 1.什么是 Docker Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目&…

Joern环境的安装(Windows版)

Joern环境的安装(Windows版) 网上很少有关于Windows下安装Joern的教程&#xff0c;而我最初使用也是装在Ubuntu虚拟机中&#xff0c;这样使用很占内存&#xff0c;影响体验感。在Windows下使用源码安装Joern也是非常简单的过程&#xff1a; 提前需要的本地环境&#xff1a; …

基于YOLOv8深度学习的智能肺炎诊断系统【python源码+Pyqt5界面+数据集+训练代码】深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

图像处理中,采用极线约束准则来约束特征点匹配搜索空间,理论上在极线上进行搜索。这里的极线是什么线,怎么定义的?基本矩阵F和本质矩阵E有什么区别?

问题描述&#xff1a;图像处理中&#xff0c;采用极线约束准则来约束特征点匹配搜索空间&#xff0c;理论上在极线上进行搜索。这里的极线是什么线&#xff0c;怎么定义的&#xff1f;基本矩阵F和本质矩阵E有什么区别&#xff1f; 问题1解答&#xff1a; 极线是通过极线几何学…

多特征变量序列预测-模型代码全家桶

包括代码、文献、文件解读&#xff01;&#xff01;&#xff01; 包括多特征变量序列预处理的代码&#xff0c; 预测效果好&#xff01;&#xff01;&#xff01;性能优越 包括 完整的风速数据集&#xff0c; 以及已经生成制作好的数据集、标签&#xff0c;对应代码均可以运行…

冻结Prompt微调LM: T5 PET (a)

T5 paper: 2019.10 Exploring the Limits of Transfer Learning with a Unified Text-to-Text Transformer Task: Everything Prompt: 前缀式人工prompt Model: Encoder-Decoder Take Away: 加入前缀Prompt&#xff0c;所有NLP任务都可以转化为文本生成任务 T5论文的初衷如…

力扣刷MySQL-第四弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

GPT应用程序的上线流程

将GPT应用程序上线涉及多个步骤&#xff0c;包括开发、测试、部署和发布。以下是一般的上线流程&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 开发和测试&#xff1a; 在开发阶段&#xff0c;确保您…

Spring MVC的原理

Spring MVC中的MVC即模型-视图-控制器&#xff0c;该框架围绕一个DispatcherServlet设计而成&#xff0c;DispatcherServlet会把请求分发给各个处理器&#xff0c;并支持可配置的处理器映射和视图渲染等功能。Spring MVC的具体工作流程如下&#xff1a; &#xff08;1&#xff…

深度解析 Compose 的 Modifier 原理 -- Modifier.layout()、LayoutModifier

" Jetpack Compose - - Modifier 原理系列文章 " &#x1f4d1; 《 深入解析 Compose 的 Modifier 原理 - - Modifier、CombinedModifier 》 &#x1f4d1; 《 深度解析 Compose 的 Modifier 原理 - - Modifier.composed()、ComposedModifier 》 &#x1f4d1; 《 深…

redis安装-Linux为例

可以下载一个Shell或者MobaXterm工具&#xff0c;便于操作 在redis官网下载压缩包 开始安装 安装依赖 yum install -y gcc tcl切换目录 切换目录后直接把redis安装包拖到/user/local/src/下 cd /user/local/src/解压然后安装 #解压 tar -zxvf redis-7.2.4.tar.gz #安装 …

C语言——小细节和小知识12

一、倒置句子 将句子中的单词位置倒置&#xff0c;标点不用倒置&#xff0c;例如i love you.倒置结果是&#xff1a;you. love i。 1、两步翻转法 采用两步翻转法来实现单词位置的倒置。首先&#xff0c;它整体翻转整个字符串&#xff0c;然后再逐个翻转每个单词内的字符。 …

环形链表问题

环形链表 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置&a…

如何录制屏幕视频?让视频制作更简单!

随着数字化时代的来临&#xff0c;录制屏幕视频成为一种常见的传播和教学方式。无论是制作演示文稿、教学视频&#xff0c;还是记录游戏操作&#xff0c;屏幕录制为用户提供了强大而灵活的工具。可是您知道如何录制屏幕视频吗&#xff1f;本文将深入介绍两种常见的屏幕录制方法…