美文网首页
Java 运行时动态将源代码生成类 并执行

Java 运行时动态将源代码生成类 并执行

作者: zxbyh | 来源:发表于2023-05-09 12:42 被阅读0次

就相当于可以吧java代码当脚本语言来用. 在特定的场景下还是有必要的!

添加pom依赖

        <!--groovy-->
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>3.0.16</version>
        </dependency>

新建一个抽象类 Person

package com.yourcom.tool.base.obj;
import lombok.Data;

@Data
public abstract class Person {
    private String name;
    public abstract void sayHello();
}

接下来要演示 通过代码的字符串 动态 继承这个Persion,然后调用它的方法. 直接上代码

package cn.quick.base.obj;

import cn.hutool.core.date.DateUtil;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import groovy.lang.GroovyShell;

import java.io.File;
import java.util.concurrent.ConcurrentHashMap;

public class CompilerUtil {

    private static ConcurrentHashMap<String, Class> _clazzRecordConcurrentHashMap = new ConcurrentHashMap<>();

    public static Class generateClass(String javaFilename, String javaCode ,Boolean renew) throws Exception {

        if(renew) {
            System.out.println("nnnn!!");
            _clazzRecordConcurrentHashMap.put(javaFilename, (new GroovyClassLoader()).parseClass(javaCode));
        }
        else {
            _clazzRecordConcurrentHashMap.computeIfAbsent(javaFilename, k->{
                System.out.println("rrrr!!");
                return (new GroovyClassLoader()).parseClass(javaCode);
            });
        }

        return _clazzRecordConcurrentHashMap.get(javaFilename);

    }

    public static void runClassDm(String name,boolean renew) throws Exception {

        Person person = (Person)generateClass(
            "com.yourcom.tool.base.obj.Teacher",
            """
                package com.yourcom.tool.base.obj
                public class Teacher extends Person {
                    @Override
                    public void sayHello() {
                        System.out.println("My name is " + getName() + ", I am a teacher");
                    }
                }    
            """,
                renew
        ).newInstance();
        person.setName(name);
        person.sayHello();
    }

    public static void runScript(){
        GroovyShell groovyShell = new GroovyShell();
        //执行Groovy脚本.
        groovyShell.evaluate("println \"hello world\"");
        //执行java 脚本.
        groovyShell.evaluate("System.out.println(\"hello groovyShell\");");
    }

    public static void runClassFromFile() throws Exception {
        GroovyClassLoader loader = new GroovyClassLoader();
        Class groovyClass = loader.parseClass(new File("D:\\workspace\\rad-solution\\quick-all\\quick-base\\src\\main\\java\\cn\\quick\\base\\obj\\Student.java")); // 也可以解析字符串
        GroovyObject groovyObject = (GroovyObject) groovyClass.newInstance();
        groovyObject.invokeMethod("say", "helloWorld");
    }


    public static void main(String[] args) throws Exception {

        runScript();

        runClassFromFile();

        Long bgn = DateUtil.current();
        runClassDm("Tom",false);
        System.out.println(DateUtil.current() - bgn);
        runClassDm("Make",false);
        System.out.println(DateUtil.current() - bgn);
        runClassDm("white",true);
        System.out.println(DateUtil.current() - bgn);

    }
}

然后运行这个例子,效果如下

hello world
hello groovyShell
student say helloWorld
rrrr!!
My name is Tom, I am a teacher
20
My name is Make, I am a teacher
20
nnnn!!
My name is white, I am a teacher
37

这个的就是用了 Groovy 中的 GroovyClassLoader
关于 Groovy 更多的介绍 见
https://www.jianshu.com/p/2c6b95097b2c
https://www.bilibili.com/video/BV1xF411P7w5/

相关文章

  • Java动态代理

    动态代理是指在运行时动态生成代理类。即,代理类的字节码将在运行时生成并载入当前代理的 ClassLoader。与静...

  • java 动态代理

    动态代理动态代理可以让我们在运行时动态生成代理类,解耦程度更高。Java 动态代理的实现主要借助于 java.la...

  • 代理-jdk动态代理

    摘要 根据代理类生成的时机,代理类在运行时生成,为动态代理;本文介绍: 如何通过JDK实现的动态代理,并详细介绍使...

  • 28,序列化和反序列化

    注:serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改...

  • 说说自定义注解的场景及实现?

    注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。程序运行时,通过...

  • Java 类加载器入门

    类加载器简介 类加载器是负责加载类的对象。 它负责在运行时将 Java 类动态加载到 JVM(Java 虚拟机)。...

  • 动态代理的实现

    一.我对动态代理的理解 1.动态生成代理类java源文件2.将代理类java源文件编译为代理类class字节码文件...

  • 2019-01-06

    原理阐述 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的JDK动态代理类。...

  • SpringMVC常用的注解有哪些?

    注解原理: 注解本质是一个继承了Annotation的特殊接口,其具体实现类是Java运行时生成的动态代理类。我们...

  • 面试必考之类的加载器

    类加载器简介 类加载器负责在运行时将Java class动态加载到JVM(Java虚拟机)。而且,它们是JRE(J...

网友评论

      本文标题:Java 运行时动态将源代码生成类 并执行

      本文链接:https://www.haomeiwen.com/subject/ciyrsdtx.html