当前位置: 首页 > 工具软件 > jOOR > 使用案例 >

JOOR流式反射库

陶弘业
2023-12-01

1. 概述

JOOR = jOOR Object Oriented Reflection

是一个java反射工具包, 极小(只有4个核心类)

流式编程, 主要简化繁复的反射API使用, 没有另加反射缓存.

2. 示例

2.1 POM.xml

<dependency>
  <groupId>org.jooq</groupId>
  <artifactId>joor-java-8</artifactId>
  <version>0.9.13</version>
</dependency>

<dependency>
  <groupId>org.junit.jupiter</groupId>
  <artifactId>junit-jupiter-engine</artifactId>
  <version>5.7.0</version>
</dependency>

2.2 User.java, GetLogger.java

package demo.java.joor;

public class User {

    private static String logger = "logback";

    private long id;

    private String name;

    public User() {
        super();
    }

    public User(long id, String name) {
        this.id = id;
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public static String getLogger() {
        return logger;
    }

    public static void setLogger(String logger) {
        User.logger = logger;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

public interface GetLogger {
    String getLogger();
}

2.3 DemoJOOR.java

package demo.java.joor;

import org.joor.Reflect;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.function.Supplier;

import static org.joor.Reflect.on;
import static org.joor.Reflect.onClass;

@DisplayName("JOOR测试")
public class DemoJOOR {

    @Test
    @DisplayName("onClass测试")
    public void testOnClass() {
        Reflect reflect1 = onClass(User.class);
        Reflect reflect2 = onClass("demo.java.joor.User");
        Reflect reflect3 = onClass("demo.java.joor.User", Thread.currentThread().getContextClassLoader());

        System.out.println(reflect1.type() == reflect1.get());      // true
        System.out.println(reflect1.type() == reflect2.type());     // true
        System.out.println(reflect1.type() == reflect3.type());     // true
    }

    @Test
    @DisplayName("onObject测试")
    public void testOnObject() {
        User user = new User(1L, "LXQ");
        Reflect reflect1 = onClass(User.class);
        Reflect reflect2 = on(user);

        System.out.println(reflect1.type() == reflect2.type());     // true
        System.out.println(reflect1.get() == reflect2.get());       // false
    }

    @Test
    @DisplayName("创建对象")
    public void testCreate() {
        User user0 = onClass(User.class).create().get();            // 无参构造
        User user1 = onClass(User.class).create(1L, "LXQ").get();   // 有参构造
        System.out.println(user0);
        System.out.println(user1);
    }

    @Test
    @DisplayName("访问对象字段")
    public void testGetSet() {
        User user = new User(1L, "LXQ");

        String name = on(user).get("name");
        System.out.println(name);

        on(user).set("name", "liuxianqiang");
        System.out.println(user.getName());
    }

    @Test
    @DisplayName("调用对象方法")
    public void testCall() {
        User user = new User(1L, "LXQ");

        String name = on(user).call("getName").get();
        System.out.println(name);

        on(user).call("setName", "liuxianqiang");
        System.out.println(user.getName());
    }

    @Test
    @DisplayName("访问类字段")
    public void testGetSet4Static() {
        String logger = onClass(User.class).get("logger");
        System.out.println(logger);

        onClass(User.class).set("logger", "log4j");
        System.out.println(User.getLogger());
    }

    @Test
    @DisplayName("调用类方法")
    public void testCall4Static() {
        String logger = onClass(User.class).call("getLogger").get();
        System.out.println(logger);

        onClass(User.class).call("setLogger", "log4j");
        System.out.println(User.getLogger());
    }

    @Test
    @DisplayName("创建代理")
    public void testAsProxy() {
        User user = new User(1L, "LXQ");
        GetLogger getLogger = on(user).as(GetLogger.class);
        System.out.println(getLogger instanceof User);              // false
        System.out.println(getLogger instanceof GetLogger);         // true
        System.out.println(getLogger.getLogger());
    }

    @Test
    @DisplayName("实时编译")
    public void testCompile() {
        Supplier<String> supplier = Reflect.compile(
                "com.example.HelloWorld",
                "package com.example;\n" +
                        "class HelloWorld implements java.util.function.Supplier<String> {\n" +
                        "    public String get() {\n" +
                        "        return \"Hello World!\";\n" +
                        "    }\n" +
                        "}\n").create().get();
        System.out.println(supplier.get());
    }
}

3. 源码分析

3.1 Reflect 和 ReflectException

反射工具类, 流式编程, 内部设计精巧.

  1. Reflect
    内部属性:
    type及object

    起始方法:
    onClass(访问类的属性及方法或创建对象)
    onObject(访问对象的属性及方法)

  2. ReflectException
    统一封装反射相关异常

3.2 Compile 和 CompileOptions

java动态编译工具类 (依赖Java Compiler API)

编译源码成字节码数组, 并用类加载器加载, 再onClass.

4. 参考

 类似资料: