当前位置: 首页 > 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&…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...