java - 如何使用带反射的动态加载界面?

标签 java reflection

我正在尝试使用反射来动态加载 Log4j2 库和方法。目标是让我的程序在类路径中找到 Log4j2 时使用它,如果未找到 Log4j2 则简单地登录到控制台。它适用于标准日志方法,但我找不到如何将这些方法与供应商一起使用。

import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.function.Supplier; // This java 8 interface happens to have the same signature as the Log4j2 Supplier interface

public class Test() {
    public static void main(String[] args) {
        try {
            // Starting by loading Log4j2 classes and methods
            ClassLoader classLoader = B.class.getClassLoader();
            Class<?> classLogManager = classLoader.loadClass("org.apache.logging.log4j.LogManager");
            Method methodGetLogger = classLogManager.getMethod("getLogger");
            Class<?> interfaceSupplier = classLoader.loadClass("org.apache.logging.log4j.util.Supplier");
            Object logger = methodGetLogger.invoke(null);
            Method methodFatal = logger.getClass().getMethod("fatal", interfaceSupplier);

            // Now trying an ugly trick, but it does not work
            Supplier<String> fatalSupplier = new Supplier<String>() {
                @Override
                public String get() {
                    System.out.println("fatal log was evaluated");
                    return "fatal";
                }

            };
            methodFatal.invoke(logger, fatalSupplier);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

我当然得到以下错误:

java.lang.IllegalArgumentException: argument type mismatch

有没有什么方法可以创建一个与 Supplier 接口(interface)(Log4j 接口(interface))匹配的对象,而无需静态加载任何 Log4j2 类?

最佳答案

失败的原因是 java.util.function.Supplier 不是 org.apache.logging.log4j.util.Supplier 的子类型。

替换行

methodFatal.invoke(logger, fatalSupplier);

通过

Object newProxyInstance = Proxy.newProxyInstance(classLoader, new Class[]{interfaceSupplier}, new InvocationHandler() {

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //TODO check method
        return fatalSupplier.get();
    }
});
methodFatal.invoke(logger, newProxyInstance);

关于java - 如何使用带反射的动态加载界面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35299056/

相关文章:

java - 不等于 hql 中的查询不起作用

java - JFileChooser 的 Windows 外观

java - 新鲜的eclipse和tomcat中的错误

c# - Enumerable.Contains 与 MethodInfo

.net - NUnit API 和以编程方式运行测试

java - 需要获取 Android Table View 中特定 textView 的值

java - 使代码可供其他子类和子子类使用

java - 通过反射向类添加新方法

java - 根据实现中使用的泛型(应用类型)使用接口(interface)的一种实现

java - 尽管 MethodHandle 正常,为什么我在 invokeExact 上收到 WrongMethodTypeException