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

时间:2015-09-15 07:14:38

标签: java logging reflection runtime access-modifiers

我正在创建一个JCL日志记录桥,它可以运行多个(比如说两个)日志记录实现(比如log4j)。根据所有这些实现的配置,桥接器会自定义全局决定是否记录,而不是记录到所有底层实现或不记录任何底层实现。

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

  • 公开isLevelEnabled()以测试“可记录性”
  • public logLevel(msg)使用测试方法并最终通过 - >
  • 记录消息
  • 受保护logInternal(lvl, msg),无需额外测试即可记录

现在,如果启用了level,我自定义决策,我不能使用做出标准决策的公共日志方法,我需要直接使用protected方法。

我知道,我可以从同一个包中访问受保护的成员,所以我添加了一个“入侵者”类,其包含与目标实现的记录器类相同的包:

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);
  }
}

直到我在应用程序服务器上运行代码时,这才起到了作用,该应用程序服务器提供了由我的应用程序之外的不同类加载器加载的日志实现之一。我得到了IllegalAccessException。这就是我学习运行时包的方法(例如quick explanation here)。

我可以通过授予可访问性来反射调用方法,我甚至可以自动测试运行时包,并在直接调用和反射之间进行选择。但是反射总是在运行应用程序的应用程序服务器上使用。由于日志记录是一种广泛使用的活动,因此反射是一种瓶颈。

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

1 个答案:

答案 0 :(得分:2)

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

您可以使用子类记录器。

最简单的解决方案可能是使用反射。我会检查你的应用程序服务器也不会阻止它。