我正在制作一个 JCL 日志桥,它可以在多个(假设是两个)日志实现(如 log4j)上运行。根据所有这些实现的配置,桥接器会做出是否记录日志以及是否记录所有底层实现或不记录任何底层实现的自定义全局决策。
日志记录实现通常具有如下方法:
- public
isLevelEnabled()
用于测试“可记录性” - public
logLevel(msg)
使用测试方法并最终通过 -> 记录消息 - protected
logInternal(lvl, msg)
,无需额外测试即可记录
现在,由于如果启用级别,我会做出自定义决策,因此我无法使用做出标准决策的公共(public)日志方法,而需要直接使用 protected 方法。
我知道,我可以从同一个包访问 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 )。
我可以通过授予可访问性来通过反射调用该方法,我什至可以对运行时包进行自动测试,并在直接调用和反射之间进行选择。但反射总是在应用程序运行的应用服务器上使用。由于日志记录是一项广泛使用的 Activity ,因此反射是这里的瓶颈。
所以我问:是否有更好(更快)的方法从不同的运行时包调用 protected 方法(或者通过 log4j 进行记录而不进行决策)?
最佳答案
您可以通过创建自己的代码版本来更改对公共(public)的访问权限,或者
您可以使用子类 Logger 来代替。
最简单的解决方案可能是使用反射。我会检查您的应用程序服务器是否也阻止了这种情况。
关于java - 有没有一种方法可以在不反射的情况下从不同的运行时包访问 protected 类成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32579909/