我当前的构建主管在理论上有一个好主意 - 构建一个自定义Log4J appender,它接受Spring管理的bean并使用它们将错误记录到除标准日志文件之外的各种其他源。但是,除了创建一个在启动时使用应用程序上下文初始化的单例(代码片刻),我似乎无法想到在Log4J appender中检索Spring托管bean的任何其他选项。
public class SpringSingleton implements ApplicationContextAware {
private static ApplicationContext context;
public SpringSingleton() {
super();
}
public static ApplicationContext getContext() {
return SpringSingleton.context;
}
public void setApplicationContext(ApplicationContext context) {
if(SpringSingleton.context != null) {
throw new IllegalStateException("Context is already set!");
}
SpringSingleton.context = context;
}
}
理想情况下,这些属性可以像Spring中的bean一样通过依赖注入设置 - 无论初始化多少个appender,bean引用都不会改变。有什么想法吗?
答案 0 :(得分:7)
由于log4j必须在 Spring之前初始化,因此你将遇到一个boostrap问题。无论您使用的是custom configuration还是Log4j的标准初始化程序,它都必须在应用程序上下文之前启动。
现在,你可以在理论上使你的自定义appender“懒惰地”自己初始化(或者通过你上面建议的方法或者通过使appender自己成为“半”单例 - 例如appender类有一个静态实例字段,它由{填充} {1}}方法;这样你可以在Spring中创建appender本身作为bean),但它看起来有些混乱和不一致。
另一种方法是在Spring上下文初始化后动态重新配置Log4j;例如写一个listener来捕获afterPropertiesSet()
,从上下文中获取所有类型为ContextStartedEvent
的bean,并将它们添加到Log4j配置中。这也可以让你创建你的appender作为bean,但避免单身麻烦。
答案 1 :(得分:0)
有点晚,但我希望这可以帮助别人。我已在以下链接中提供的答案中记录了此问题的解决方案: