JavaDynamilizer - java语言的动态化支持框架

JavaDynamilizer(JDER)是一个Java动态化库,模仿Groovy的动态逻辑,提供面向切面编程支持。本文介绍了JDER的基本概念、用法、动态类型、代码插桩和热更新的实现,以及框架的底层逻辑和多平台兼容性。通过JDER,开发者可以动态地改变对象行为,实现代码插桩和热更新,增强程序的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一次写博,可能表述不是很清晰,将就看吧))

目录

  • 简介
  • 基本使用说明
  • 使用样例
  • 底层逻辑
  • 多平台兼容性
  • 后记

简介

java作为一个老牌的静态编程语言,它的一些特性/语法在今天看来已经过于陈旧,且其面向对象编程逻辑也十分封闭,在我的某一个动态需求的开发过程中,java语言的弊端越来越显著,同时我也发现脚本语言的编程逻辑似乎能从一定程度上优化编程形式,于是我便把目光放到了个groovy上,参考groovy的动态逻辑,开发了java动态化编程框架——JavaDynamilizer

JavaDynamilizer(可简写为JDER)是一个通用的java动态化库,为java开发者提供了类似脚本语言的动态编程支持,允许开发者以函数和变量的形式,且此库以委托形式运行,可以很好的支持已有项目的局部动态化。一定程度上,框架可以很好的提高程序的灵活性,并且从程序上提供了对面向切面编程(Aspect Oriented Programming, AOP)的支持。

项目仓库托管于github:
https://github.com/EB-wilson/JavaDynamilizer

发布在jitpack,使用时只需要添加依赖即可,以gradle为例:

dependencies {
   
    ......
    implementation "com.github.EB-wilson:JavaDynamilizer:$version"
    ......
}

基本用法说明

JDER在使用上主要关注的就是以下几个概念:

  • 动态类型(DynamicClass)
  • 动态对象(DynamicObject)
  • 动态创建器(DynamicMaker)
  • 函数(Function)
  • 变量(Variable)

他们之间的关系可以用一张图片表示:
image
这与java本身的类结构其实比较相似,但不同的是动态类型提供给对象的只是初始状态的样版,动态对象创建后会按动态类描述的信息初始化默认状态,而动态类和动态对象的行为都是可变的。

动态创建器在内部有一个默认实现,可以通过DynamicMaker中的静态方法getDefault方法获得默认实例,关于动态创建器的自定义实现在后文会讲述,现在我们可以使用动态创建器的newInsance方法创建动态对象,该方法有多个重载:

public DynamicObject newInstance(DynamicClass dynamicClass)
public DynamicObject newInstance(Class<?>[] interfaces, DynamicClass dynamicClass)
public <T> DynamicObject<T> newInstance(Class<T> base, DynamicClass dynamicClass, Object... args)
public <T> DynamicObject<T> newInstance(Class<T> base, Class<?>[] interfaces, DynamicClass dynamicClass, Object... args)

它们的区别只在于给出的信息,最终实际上都会传入到最后一个,各自的使用及效果参阅如下代码:

DynamicMaker maker = DynamicMaker.getDefault();
DynamicClass Demo = DynamicClass.get("Demo"); //获取名为"Demo"的动态类,类型若不存在会创建一个新的
DynamicObject<?> dyObj = maker.newInstance(Demo); //从动态类型创建一个动态对象,对象仅能被分配给Object
Object obj1 = dyObj;

DynamicObject<Runnable> dyRun = maker.newInstance(new Class[]{
   Runnable.class}, Demo); //从动态类创建一个动态对象,对象实现了Runnable接口,可分配给Runnable
Runnable run = (Runnabl) dyRun; //可正确分配

DynamicObject<ArrayList> dyList = maker.newInstnce(ArrayList.class, Demo); //从Arraylist委托创建一个动态对象,对象是ArrayList的子类实例,可分配给ArrayList,无构造函数参数
ArrayList obj2 = dyObj1.self(); //可正确分配,self()是泛型指针,实际上你是可以直接(ArrayList) dyObj进行类型转换的

DynamicObject<HashMap> dyMap = maker.newInstance(HashMap.class, new Class[]{
   Runnable.class}, Demo); //从HashMap委托创建一个动态对象,对象实现了Runnable接口,可分配给HashMap和Runnable
HashMap<?, ?> map = dyMap.self();
Runnable run = (Runnable) dyMap;//均可正确分配

上面的代码所创建的所有实例均为DynamicObject,均具有动态对象的特征,即可以以函数的方式访问和更改其方法行为,插入新的函数等,且对于基类和接口的方法都是正确的函数化的,即java对其方法的引用与通过动态类型调用函数的效果是一致的,即对于上面的代码上下文有:

dyMap.invokeFunc("put", "key1", "hello world!");

map.put("key1", "hello world!");

这两段代码的效果是完全一致的。同样的,将函数获取为变量的效果也是相同的:

Function<HashMap, Object> func = dyMap.getFunction("put", Object.class, Object.class);
func.invoke(dyMap, "key1", "hello world!");

变更动态对象的行为

动态类型的行为函数(Funcion)和变量(Variable)构成,通过设置/变更对象的函数和变量就可以改变对象的行为(变量也可以保存函数),即:对象的行为是动态可变的,函数和变量可以进行添加,修改和读取,但是不能删除。
变更对象的函数除直接通过动态对象的setFunc方法设置之外,默认情况还可以变更动态对象的动态类描述的行为来改变,后文会进一步说明动态类型。

例如,在上文代码的上下文中,进行如下操作:

dyMap.setFunc("put", (s, a) -> {
   
  System.out.println("map putted, key: " + a.get(0) + ", value: " + a.get(1));
  return s.superPointer().invokeFunc("put", a); //这相当于对方法调用super指针,执行其超方法
});

这样做以后,对这个map无论是以java直接对put方法进行调用,还是通过对象的invokeFunc方法执行函数,结果都是会将被添加的键值对打印到系统输出流:

dyMap.invokeFunc("put", "key2", 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值