Log4j的默认初始化通过查找和使用URL进行配置的过程。然后,您如何找出最终使用的URL,而不必自己编写相同的过程?(如果您必须自己编写代码,则可能无法获得与log4j完全相同的代码,并且在将来的发行版中它可能会更改。)
如果您愿意使用AspectJ LTW(加载时编织),则可以看看LogManagerIan Roberts提到的静态初始化。在 log4j 1.2.14中, 它看起来像这样:
LogManager
static { // (...) // if there is no default init override, then get the resource // specified by the user or the default config file. if (override == null || "false".equalsIgnoreCase(override)) { // (...) URL url = null; // (...) // If we have a non-null url, then delegate the rest of the // configuration to the OptionConverter.selectAndConfigure method. if (url != null) { LogLog.debug("Using URL [" + url + "] for automatic log4j configuration."); OptionConverter.selectAndConfigure( url, configuratorClassName, LogManager.getLoggerRepository() ); } else { LogLog.debug("Could not find resource: [" + configurationOptionStr + "]."); } } }
显然,如果可以确定默认URL,OptionConverter.selectAndConfigure(URL, ..)则将在静态块内的某个位置调用该URL ,以便使用该URL 初始化 log4j 。
OptionConverter.selectAndConfigure(URL, ..)
通过 AspectJ ,捕获该方法调用非常简单:
import java.net.URL; import org.apache.log4j.helpers.OptionConverter; import org.apache.log4j.LogManager; public aspect Log4jAspect { before(URL defaultURL) : within(LogManager) && cflow(staticinitialization(LogManager)) && call(* OptionConverter.selectAndConfigure(URL, ..)) && args(defaultURL, ..) { System.out.println("log4j default URL = " + defaultURL); } }
在散文中,此代码表示:
OptionConverter.selectAndConfigure
如果没有默认URL,则不会打印任何内容。无需打印URL,您可以将其分配给任何类或任何您喜欢的静态成员。
这是针对您的问题的解决方案,我对其进行了测试并成功运行。即使解决方案使用的是您没有想到的技术,我也很高兴收到悬赏解答您的问题。但这解决了问题。:-)
Edit: It is also possible to explicitly intercept the log call in the case that no default URL is found, even though I do not think it is necessary. I just wanted to mention it.