有没有办法从不同的运行时包访问受保护的 class 成员而无需反射?

Is there a way to access protected class members from different runtime package without reflection?

我正在制作一个 JCL 日志记录桥,它在多个(比如说两个)日志实现(比如 log4j)上运行。根据所有这些实现的配置,桥接器做出自定义全局决定是记录还是记录到所有或 none 底层实现。

日志记录实现通常有这样的方法:

现在由于我在启用级别时做出自定义决定,所以我不能使用做出标准决定的 public 日志方法,我需要直接使用受保护的方法。

我知道,我可以从同一个包访问受保护的成员,所以我添加了一个 "intruder" class 与目标实现的记录器 class 相同的包:

package com.log.lib;

//logging library logger in dependency jar
public class Logger {
  protected void logInternal(int lvl, String msg){
    //library logging without additional level testing
  }
}
package com.log.lib;

//my class to access protected method of library logger
public class LoggerAccessor {
  public void log(Logger logger, int lvl, String msg) {
    logger.logInternal(lvl, msg);
  }
}

直到我 运行 应用程序服务器上的代码提供了一个由与我的应用程序不同的 classloader 加载的日志记录实现,这才有效。我得到了一个 IllegalAccessException。这就是我了解 runtime packages(例如 quick explanation here)的方式。

我可以通过 g运行 可访问性通过反射调用该方法,我什至在直接调用和反射之间自动测试运行时包和 select。但是反射总是在应用运行的应用服务器上使用。由于日志记录是一种广泛使用的 activity,反射在这里是一种瓶颈。

所以我问:有没有更好(更快)的方法从不同的运行时包调用受保护的方法(或者通过 log4j 记录日志而不做决定)?

您可以通过创建您自己的代码版本来更改对 public 的访问权限,或者

您可以改用子类记录器。

最简单的解决方案可能是使用反射。我会检查您的应用程序服务器是否也不会阻止这种情况。