刚来公司就接了一个不发版直接改代码的需求

北京儿童扁平疣医院 http://news.39.net/bjzkhbzy/210729/9247303.html

前言

前几天突然接到一个技术需求,想要做一个功能。前端有一个表单,在页面上可以直接写java代码,写完后就能保存到数据库,并且这个代码实时生效。这岂非是不用发版就可以随时改代码了吗?而且有bug也不怕,随时改。

适用场景:代码逻辑需要经常变动的业务。

核心思想

页面改动java代码字符串

java代码字符串编译成class

动态加载到jvm

实现重点

JDK提供了一个工具包javax.tools让使用者可以用简易的API进行编译。

这些工具包的使用步骤:

获取一个javax.tools.JavaCompiler实例。

基于Java文件对象初始化一个编译任务CompilationTask实例。

因为JVM里面的Class是基于ClassLoader隔离的,所以编译成功之后可以通过自定义的类加载器加载对应的类实例

使用反射API进行实例化和后续的调用。

1.代码编译

这一步需要将java文件编译成class,其实平常的开发过程中,我们的代码编译都是由IDEA、Maven等工具完成。

内置的SimpleJavaFileObject是面向源码文件的,而我们的是源码字符串,所以需要实现JavaFileObject接口自定义一个JavaFileObject。

publicclassCharSequenceJavaFileObjectextendsSimpleJavaFileObject{publicstaticfinalStringCLASS_EXTENSION=".class";publicstaticfinalStringJAVA_EXTENSION=".java";privatestaticURIfromClassName(StringclassName){try{returnnewURI(className);}catch(URISyntaxExceptione){thrownewIllegalArgumentException(className,e);}}privateByteArrayOutputStreambyteCode;privatefinalCharSequencesourceCode;publicCharSequenceJavaFileObject(StringclassName,CharSequencesourceCode){super(fromClassName(className+JAVA_EXTENSION),Kind.SOURCE);this.sourceCode=sourceCode;}publicCharSequenceJavaFileObject(StringfullClassName,Kindkind){super(fromClassName(fullClassName),kind);this.sourceCode=null;}publicCharSequenceJavaFileObject(URIuri,Kindkind){super(uri,kind);this.sourceCode=null;}

OverridepublicCharSequencegetCharContent(booleanignoreEncodingErrors)throwsIOException{returnsourceCode;}

OverridepublicInputStreamopenInputStream(){returnnewByteArrayInputStream(getByteCode());}//注意这个方法是编译结果回调的OutputStream,回调成功后就能通过下面的getByteCode()方法获取目标类编译后的字节码字节数组

OverridepublicOutputStreamopenOutputStream(){returnbyteCode=newByteArrayOutputStream();}publicbyte[]getByteCode(){returnbyteCode.toByteArray();}}

如果编译成功之后,直接通过CharSequenceJavaFileObject#getByteCode()方法即可获取目标类编译后的字节码对应的字节数组(二进制内容)

实现ClassLoader

因为JVM里面的Class是基于ClassLoader隔离的,所以编译成功之后得通过自定义的类加载器加载对应的类实例,否则是加载不了的,因为同一个类只会加载一次。

主要


转载请注明:http://www.aierlanlan.com/cyrz/4191.html

  • 上一篇文章:
  •   
  • 下一篇文章: