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

用反射模拟IOC模拟getBean

IOC就是spring的核心思想之一:控制反转。这里不再赘述,看我的文章即可了解:

spring基础思想IOC

其次就是java的反射,反射机制是spring的重要实现核心,今天我看spring的三级缓存解决循坏引用的问题时,发现一个bean的生命周期与java对象的产生流程具备高度相似性,接着我就去重温了一下bean的创建流程,发现一个bean实例从无到有经历的过程非常有意思,spring用极其优雅的代码实现了用反射和各种map数据结构实现了bean的流水线式生产,非常优雅,于是我就尝试用反射写一个逆向生成实例对象的小玩意。

那么前置需要了解一个对象生成的过程:

我将对象的创建过程总结为:

检查常量池是否存在该对象的符号引用并确定是否经过类加载过程,都没有则进行类加载过程。

为新生对象分配内存(两种方式:指针碰撞和空闲列表<指针碰撞涉及到当指针调动频繁时为了避免出现脏读,采取本地线程分配缓冲TLAB的优先分配情况>)并将除对象头外的其他内存空间赋值W为0。

设置对象头。

对象的初始化,这个就是执行你的构造方法的过程,给你需要的字段赋值你想要定义的值。

补充一下其中的细节:为新生对象分配内存过程中,首先一个对象在类加载完成后它所需要的内存大小是完全确定的,分配内存的过程实际上就是在java堆里划分一块等大的内存给它,但是该怎么划分呢?如果java堆的内存布局是严格的顺序分配,即一边是使用过的,一边是空闲的,那么就会采取指针碰撞的方式分配内存,所谓的指针在空闲区与使用区的分界线处,收到内存需求时,指针向后移动直到移动所覆盖的长度等于java对象所需要的内存大小时停止并进行分配。但如果java堆的内存布局是碎片化的不连续的呢?我们就只能维护一个列表,这个列表记录了所有java堆空闲区的大小与位置信息,分配时只需要查找最适合新生对象的区域分配即可。

注意:java堆是否规整是由垃圾收集器的能力决定的,是否带有空间压缩整理的能力。当我们采用的收集器是Serial与Parnew时是用指针碰撞的方式分配的,当采用的是CMS垃圾收集器的时候,则是需要使用麻烦的空闲区表分配。


这里我们着重的去关注属性与方法的填充即可:一个对象的灵魂就是它的属性与方法:

整个工具用到的核心属性:

    private static volatile Constructor<?> constructor;private static volatile Object newInstance;private static volatile Map<String, Method> methodMap;

我们先看看这几个方法的作用:

  public static Constructor<?> getConstructor(Object dataType) {Class<?> typeClass = dataType.getClass();try {Constructor<?> constructor = typeClass.getConstructor();constructor.setAccessible(true);return constructor;} catch (NoSuchMethodException e) {e.printStackTrace();return null;}}

获取类型的构造器,注意这可是无参构造,如果你没有无参构造那么很有可能报错,因为我们也不知道它有多少属性对吧?(时刻记住咱们是逆向!!!不知道这个类型里有什么!!!一切都是反射带来的信息)

public static void fillValueToNewInstance(Object dataType, Map<String, Object> initialMap) throws Exception {constructor = getConstructor(dataType);Class<?> typeClass = dataType.getClass();Field[] declaredFields = typeClass.getDeclaredFields();Iterator<Field> fieldIterator = Arrays.stream(declaredFields).iterator();newInstance = constructor.newInstance();while (fieldIterator.hasNext()) {Field field = fieldIterator.next();field.setAccessible(true);if (initialMap != null)field.set(newInstance, initialMap.get(field.getName()));}}

获取属性并填充属性值,这里也顺带着将属性给进去了。

 public static Method[] getMethodArray(Object dataType) {return dataType.getClass().getDeclaredMethods();}

获取一切方法组成方法数组。

  public static void fillMethodMap(Object dataType) {methodMap = new HashMap<>();Method[] methodArray = getMethodArray(dataType);Iterator<Method> iterator = Arrays.stream(methodArray).iterator();while (iterator.hasNext()) {Method method = iterator.next();method.setAccessible(true);methodMap.put(method.getName(), method);}}

将方法存到方法集合中去存储。

 public static Object useMethod(String methodName, @Nullable Object... parameters) throws Exception {return methodMap.get(methodName).invoke(newInstance, parameters);}

使用方法要通过名称。

    @SneakyThrowspublic static Object getBean(Object dataType, Map<String, Object> parameterMap) {fillValueToNewInstance(dataType, parameterMap);fillMethodMap(dataType);return newInstance;}

getBean方法。

  public static void main(String[] args) throws Exception {Map<String,Object> map = new HashMap<>();map.put("name","xu");map.put("age",Integer.valueOf(18));map.put("sex",'女');Person bean = (Person) getBean(new Person(), map);System.out.println(bean.toString());System.out.println(useMethod("toString"));}

测试方法。类型信息如下:

class Person {private String name;private Integer age;private Character sex;//无参构造绝对不能少public Person() {}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", sex=" + sex +'}';}
}

测试结果如下:

这里我们可没有用Person person = new Person();的方式实例化对象,用反射实现了对象的实例化。


里面用到关于反射的方法我列下来:

getDeclaredFields 获取域属性对象

getName 获取属性名称

getType 获取属性类型的字节码文件

setAccessible(true) 设置暴力破解,获取对私有属性的使用

getDeclaredMethods 获取全部方法数组

getClass 获取字节码文件

getConstructor 获取无参构造器


相关文章:

用反射模拟IOC模拟getBean

IOC就是spring的核心思想之一&#xff1a;控制反转。这里不再赘述&#xff0c;看我的文章即可了解&#xff1a;spring基础思想IOC其次就是java的反射&#xff0c;反射机制是spring的重要实现核心&#xff0c;今天我看spring的三级缓存解决循坏引用的问题时&#xff0c;发现一个…...

【Ap AutoSAR入门与实战开发02】-【Ap_s2s模块01】: s2s的背景

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 1 s2s的背景?2 AUTOSAR 方法应支持车辆的无缝开发2.1 面向服务的ECU的解读2.2 面向信号的ECU的解读2.3 通过网关ECU实现转换1 s2s的背景? Cp AutoSAR基于传统的can,lin,flexray总线的通信,一般是面向信号设…...

C语言数据结构(3)----无头单向非循环链表

目录 1. 链表的概念及结构 2. 链表的分类 3. 无头单向非循环链表的实现(下面称为单链表) 3.1 SListNode* BuySListNode(SLTDateType x) 的实现 3.2 void SListPrint(SListNode* plist) 的实现 3.3 void SListPushBack(SListNode** pplist, SLTDateType x) 的实现 3.4 voi…...

Android 实现菜单拖拽排序

效果图简介本文主角是ItemTouchHelper。它是RecyclerView对于item交互处理的一个「辅助类」&#xff0c;主要用于拖拽以及滑动处理。以接口实现的方式&#xff0c;达到配置简单、逻辑解耦、职责分明的效果&#xff0c;并且支持所有的布局方式。功能拆解功能实现4.1、实现接口自…...

通过window.open打开新的页面并修改样式添加内容

const img new Image(); img.src res; //res是图片的路径地址 const newWin window.open(, _blank); newWin.document.write(img.outerHTML); // newWin.document.body.style.background #000; newWin.document.body.style.textAlign center; newWin.document.body.oncl…...

Java中 Synchronized 的用法

《编程思想之多线程与多进程(1)——以操作系统的角度述说线程与进程》一文详细讲述了线程、进程的关系及在操作系统中的表现&#xff0c;这是多线程学习必须了解的基础。本文将接着讲一下Java线程同步中的一个重要的概念synchronized. synchronized是Java中的关键字&#xff0c…...

Rust语言的基本介绍

rust缘起和目标 rust的英文是锈菌&#xff0c;是一种真菌&#xff0c;这种真菌的生命力非常顽强&#xff0c;其 在生命周期内可以产生多达5种孢子类型&#xff0c;这5种生命形态还可以相互转 化。“Rust”也有“铁锈”的意思&#xff0c;暗合“裸金属”之意&#xff0c;代表了R…...

新冠小阳人症状记录

原想挺过春节后再养&#xff0c;发现事与愿违。生理期期间抵抗力下降&#xff0c;所以在生理期第二天就有些症状了。可能是生理期前一天出去采购食物染上&#xff0c;也可能是合租夫妻染上。anyway&#xff0c;记录下自己的症状与相应有效的偏方&#xff1a; 第一天&#xff1a…...

SQL零基础入门学习(十四)

上篇&#xff1a;SQL零基础入门学习&#xff08;十三&#xff09; SQL NULL 值 NULL 值代表遗漏的未知数据。 默认地&#xff0c;表的列可以存放 NULL 值。 如果表中的某个列是可选的&#xff0c;那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该…...

Excel工作表不能移动或复制?看看是不是这两个原因

Excel工作表不能移动或复制&#xff1f;今天来看看如何解决。 大家都知道&#xff0c;Excel表格分为工作簿和工作表&#xff0c;工作簿就是整个Excel文件&#xff1b;工作簿里面&#xff0c;也就是Excel表可以有多个工作表。 而各个工作表之间是可以相互移动或复制的&#xf…...

利用递归实现括号匹配

案例引入以下则是各个字符串经过括号处理之后的结果&#xff1a;12((21))(12-->12(21)1232((((2121)212(21)-->32(2121)212(21)ABDF((SA)SA)SA(SA)SA(((-->ABDF((SA)SA)SA(SA)SA算法思路&#xff1a;这个问题的解决方法就是将字符按顺序逐一加入到新的string容器store…...

14.线程数量怎么制定?

什么是CPU 密集型任务和耗时 IO 型任务 &#xff1f; CPU 密集型任务 CPU 密集型任务&#xff0c;比如加密、解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务。 耗时 IO 型任务 数据库、文件的读写&#xff0c;网络通信等任务&#xff0c;这种任务的特点是并不会特别消耗…...

C++中STL标准模板库学习记录

文章目录&#xff1a;1.vector1.1 遍历方式1.2 构造函数1.3 容量大小问题1.4 插入和删除1.5 存取值1.6 交换两个vectot的元素1.7 预定义存储空间2.string3. deque4. stack4.1 常用函数5. queue5.1 特点5.2 方法6. list6.1 优点6.2 缺点6.3 构造函数6.4 交换6.5 大小6.6 插入和删…...

《数据库系统概论》学习笔记——第六章 关系数据理论

教材为数据库系统概论第五版&#xff08;王珊&#xff09; 这一章重点在于各种范式的概念和将低级范式转为高级范式。一定要看多值依赖和4NF&#xff08;因为这个概念很绕又烦&#xff0c;但是期中期末都考了&#xff09;。最后计算题就是一定要会&#xff1a;算闭包&#xff0…...

Odoo | Webserivce | 5分钟学会【JSONRPC】接口开发

文章目录Odoo - JsonRPC1. Odoo内方法结构&#xff08;接收端&#xff09;2. POST接口请求结构&#xff08;发送端&#xff09;3. 实例测试Odoo - JsonRPC 1. Odoo内方法结构&#xff08;接收端&#xff09; # -*- coding: utf-8 -*- import odoo import logging import trac…...

搜广推 NeuralCF - 改进协同过滤+矩阵分解的思想

😄 NeuralCF:2017新加坡国立大学提出。【后文简称NCF】 😄 PNN:2016年上海交通大学提出。 文章目录 NeuralCF动机原理general NCFNCF终极版(GMF+MLP的结合)缺点优点ReferenceNeuralCF 动机 前面学了MF,可知MF在用户-物品评分矩阵的基础上做矩阵分解(用户矩阵Q和物品…...

dbever连接kerberos认证的hive

文章目录一、本地安装kerberos客户端二、本地kerberos客户端登录三、dbever连接hive一、本地安装kerberos客户端 下载地址&#xff1a;https://web.mit.edu/kerberos/dist/index.html 安装&#xff1a;下一步或者自定义安装即可 安装后会自动生成配置文件&#xff1a;C:\Pro…...

pom依赖产生的各种问题

文章目录问题一(org.apache.ibatis.session.Configuration)解决方法问题二(ERROR StatusLogger No log4j2)解决方法问题三(com.google.common.util.concurrent)解决方法问题四(start bean documentationPluginsBootstrapper)解决方法问题五(Unable to infer base url. )解决办法…...

RPC编程:RPC框架设计目标

一&#xff1a;前导知识 Http是超文本传输协议&#xff0c;跨平台性非常好。Http可以传输文本&#xff0c;更多的时候传输的是文本&#xff0c;我们也是可以传输二进制的&#xff0c;我们基于Http进行下载的时候&#xff0c;就是走的Http协议。 Tcp协议&#xff0c;处理的时候…...

RBAC 权限模型介绍

RBAC 权限&#xff1a; 一、关系&#xff1a; 这基于角色的访问控制的结构就叫RBAC结构。 二、RBAC 重要对象&#xff1a; 用户&#xff08;Employee&#xff09;&#xff1a;角色施加的主体&#xff1b;用户通过拥有某个或多个角色以得到对应的权限。角色&#xff08;Role&…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

Angular微前端架构:Module Federation + ngx-build-plus (Webpack)

以下是一个完整的 Angular 微前端示例&#xff0c;其中使用的是 Module Federation 和 npx-build-plus 实现了主应用&#xff08;Shell&#xff09;与子应用&#xff08;Remote&#xff09;的集成。 &#x1f6e0;️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

适应性Java用于现代 API:REST、GraphQL 和事件驱动

在快速发展的软件开发领域&#xff0c;REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名&#xff0c;不断适应这些现代范式的需求。随着不断发展的生态系统&#xff0c;Java 在现代 API 方…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

【无标题】湖北理元理律师事务所:债务优化中的生活保障与法律平衡之道

文/法律实务观察组 在债务重组领域&#xff0c;专业机构的核心价值不仅在于减轻债务数字&#xff0c;更在于帮助债务人在履行义务的同时维持基本生活尊严。湖北理元理律师事务所的服务实践表明&#xff0c;合法债务优化需同步实现三重平衡&#xff1a; 法律刚性&#xff08;债…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...