在Spring管理的Web应用程序中,在Log4J Appender中检索Spring托管bean有哪些可用选项?

时间:2009-11-13 17:09:54

标签: spring log4j javabeans appender

我当前的构建主管在理论上有一个好主意 - 构建一个自定义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引用都不会改变。有什么想法吗?

2 个答案:

答案 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)

有点晚,但我希望这可以帮助别人。我已在以下链接中提供的答案中记录了此问题的解决方案:

log4j - Accessing spring bean from logging appender class