当前位置: 首页 > article >正文

手动创建spring bean并注入

文章目录

  • 前言
  • 一、jar包中,相同class不同类加载器加载的时候是同一个class嘛?
  • 二、利用ConfigurableListableBeanFactory手动注册bean
    • 注册bean,并自动注入依赖bean
    • 根据类型获取注入的bean,两个bean是一个吗?
  • 三、同一份字节码,class隔离,bean隔离
  • 总结


前言

注入一个bean常用的方式有几种: 加注解,spring.favorite中添加类全路径 等

今天涉及到了一个问题,就是需要在程序中,根据名字,在jar中寻找class,动态加载对象,然后变成bean 注入到spring容器中,当然还有其他问题;


一、jar包中,相同class不同类加载器加载的时候是同一个class嘛?

做如下验证,同一个jar包,通过两个类加载器加载,看是否为同一个class,整体代码如下:
测试类;

@SpringBootTest
public class ClassLoadTest {

    @Autowired
    ApplicationContext context;

    @Test
    void ss() throws Exception {
        
        String path = "D:\\Java-develop\\project\\token\\src\\main\\resources\\jar\\platform-base-system-3d-public-1.0-SNAPSHOT-plain.jar";

        URL[] urls = {new URL("file:" + path)};
        URLClassLoader urlClassLoader = new URLClassLoader(urls);
        URLClassLoader urlClassLoader1 = new URLClassLoader(urls);
        Class<?> aClass = urlClassLoader.loadClass("com.platform.base.system.system.util.StringUtils");
        Class<?> aClass1 = urlClassLoader1.loadClass("com.platform.base.system.system.util.StringUtils");

        SpringUtil.registerBean("javaInfo", aClass.newInstance());
        SpringUtil.registerBean("javaInfo1", aClass1.newInstance());


        Object javaInfo = context.getBean(aClass);
        System.out.println(javaInfo);
        Object javaInfo1 = context.getBean(aClass1);
        System.out.println(javaInfo1);
        Object bean = context.getBean("javaInfo");
        System.out.println(bean);

        System.out.println(context.getBean("javaInfo").equals(context.getBean("javaInfo1")));

    }

}

debug可以看到:
class类加载
不同的类加载器,加载同一个jar的同一个class,加载到的class也是不一样的; 分别为8554 / 8555

二、利用ConfigurableListableBeanFactory手动注册bean

注册bean,并自动注入依赖bean

  SpringUtil.registerBean("javaInfo", aClass.newInstance());
  SpringUtil.registerBean("javaInfo1", aClass1.newInstance());
  • 由于注入的bean名称不能一直,所以这里设置不同的bean名称
  • 然后将每个class初始化后,注入到spring容器中

根据类型获取注入的bean,两个bean是一个吗?

Object javaInfo = context.getBean(aClass);
System.out.println(javaInfo);
Object javaInfo1 = context.getBean(aClass1);
System.out.println(javaInfo1);

可以看到:
获取bean
这是不同的两个bean,分别为: 8547 / 8556

三、同一份字节码,class隔离,bean隔离

为什么 同一份字节码,class隔离,bean隔离?
  • 虽然是同一份字节码,但是由于是不同的类加载器加载的,所以造成了class隔离
  • 由于是不同的class,所以后续注入bean的时候,也造成了bean隔离

这样的意义在于:
当不同jar中,存在相同bean的时候,即使完全一样的class,在通过类加载器加载的时候,也不会造成问题


总结

  1. 加载jar包中的class
  2. 根据加载的class创建对象
  3. 手动创建bean,注入spring容器中
  4. 每个类加载器不同,那么加载的class也一定不同

http://www.kler.cn/a/158869.html

相关文章:

  • 帧中继原理与配置
  • 任意文件下载漏洞
  • 【不写for循环】玩玩行列
  • 【STM32】USB 简要驱动软件架构图
  • 蓝桥杯介绍
  • 【MYSQL】分库分表
  • 详解十大经典排序算法(五):归并排序(Merge Sort)
  • OSPF浅析
  • 3分钟在CentOS 7上离线安装Docker
  • 陪诊系统:基于自然语言处理的患者沟通创新
  • 如何使用 Docker 安装 Node-RED
  • 文件夹批量改名:轻松管理文件夹,随机重命名不求人
  • 线程池,及7大参数,4大拒绝策略
  • uniapp实现拨打电话跳转手机拨号界面 (ios和安卓通用)
  • Python网络爬虫环境的安装指南
  • 《opencv实用探索·十》opencv双边滤波的简单理解
  • 2023年甘肃省职业院校技能大赛(中职教师组)网络安全竞赛样题(一)
  • 【在英伟达nvidia的jetson-orin-nx上使用调试摄像头-同时开启多个摄像头-基础测试(2)】
  • 探索数据之美:深入学习Plotly库的强大可视化
  • pta模拟题(C语言7-26 整除光棍、7-27 稳赢、7-28 查验身份证、7-29 出生年、7-30 点赞)
  • 第2章 知识抽取:概述、方法
  • 【C++】const关键字的详解!!
  • 有权图的最短路径算法
  • 关于“你对SpringCloud的理解”
  • TrustZone之虚拟地址空间
  • Python sorted函数及用法以及如何用json模块存储数据