【问题标题】:Is there a way to access protected class members from different runtime package without reflection?有没有办法从不同的运行时包访问受保护的类成员而无需反射?
【发布时间】:2015-12-11 08:19:04
【问题描述】:

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

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

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

现在,由于我在启用级别时做出自定义决定,因此我无法使用做出标准决定的公共日志方法,我需要直接使用受保护的方法。

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

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 而没有它的决策)?

【问题讨论】:

    标签: java logging reflection runtime access-modifiers


    【解决方案1】:

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

    您可以改用子类 Logger。

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

    【讨论】:

    • 反射有效,但出于性能原因我不想使用它。我得到记录器实例,例如通过Logger.getLogger(name) 获取 Log4j。如何使用子类记录器?
    • @Mrkvozrout 如果反射对您来说是一个性能问题,我建议您不要使用可能会贵 1000 倍的日志记录。另一种方法是使用像 Chronicle Queue 这样的低延迟记录器,它可以在微秒内写入一条消息,但仍然要长 20 倍。但我怀疑调用反射所需的 50 纳秒不是你认为的问题是。
    • 好的,非常感谢您的建议。是的,反思毕竟没有那么慢,但我仍然想知道是否有更好、更原生的方式。不记录不是一种选择,所以为什么不让它尽可能有效
    • @Mrkvozrout 在这种情况下,我建议寻找更有效的记录方式。我将从几乎与 Chronicle-Logger 一样快的 log4j2 开始。
    • 这是个好建议。但是仍然存在记录到主要两个实现并控制决策制定(isLevelEnabled)的业务需求,并且 Log4j2 也遵循带保护方法的结构。所以让我们更多地关注这个问题的标题或最后的问题。
    猜你喜欢
    • 2012-05-14
    • 2015-09-19
    • 2018-07-21
    • 2014-02-22
    • 2012-05-03
    • 2015-12-30
    • 2016-10-01
    • 2010-09-25
    • 2015-01-30
    相关资源
    最近更新 更多