Spring Boot会使用LoggingApplicationListener
自动初始化底层日志系统。如果我正在开发的应用程序是独立的或单独运行,这是很好的。
但是我正在开发一个Web应用程序,将部署到WSO2应用服务器中,该服务器提供统一的日志记录(使用log4j),具有诸如运行时集中日志级别管理(通过Web界面)、业务报告等功能。
如果我直接使用Spring Boot,则它会完全自己记录所有内容。我的第一个尝试是删除spring-boot-starter-logging
并手动添加slf4j-api
作为provided
。这在某种程度上起作用,因为LoggingApplicationListener
现在覆盖了由WSO2提供的全局logmanager的设置(甚至导致全局appender关闭)。
我想到的唯一“解决方案”就是通过反射删除该侦听器。然后Spring Boot开始像它应该的那样行事(通过全局记录器进行记录,而不是覆盖预定义的日志级别、输出格式、appender等)。
这个“解决方案”看起来像这样:
@SpringBootApplication
public class MyApp extends SpringBootServletInitializer {
public static void main(String... args) {
SpringApplication.run(MyApp.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
try {
Field appField = SpringApplicationBuilder.class.getDeclaredField("application");
appField.setAccessible(true);
SpringApplication app = (SpringApplication)appField.get(builder);
Field listenersField = SpringApplication.class.getDeclaredField("listeners");
listenersField.setAccessible(true);
List<ApplicationListener<?>> listeners = (List<ApplicationListener<?>>) listenersField.get(app);
for (int i = listeners.size() - 1; i >= 0; --i) {
if (listeners.get(i) instanceof LoggingApplicationListener) {
listeners.remove(i);
}
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return builder.sources(MyApp.class);
}
}
在我的研究和代码分析中,是否有任何更好的解决方案可以解决我的问题,而且可能不那么hacky?