美文网首页
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 运行时动态将源代码生成类 并执行

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