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

Met*_*002 3 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

理想情况下,这些属性可以像Spring中的bean一样通过依赖注入设置 - 无论初始化多少个appender,bean引用都不会改变.有任何想法吗?

Chs*_*y76 7

因为log4j必须 Spring 之前初始化,所以你会遇到一个boostrap问题.无论您是使用自定义配置还是Log4j的标准初始化程序,它都必须在应用程序上下文之前启动.

现在,理论上你可以让你的自定义appender"懒惰地"自己初始化(或者通过你上面建议的方法或者通过使appender自己成为"半"单例 - 例如appender类有一个静态实例字段,它由afterPropertiesSet()方法填充;那样你可以在Spring中创建appender本身作为bean)但它看起来有些混乱和不一致.

另一种方法是在Spring上下文初始化后动态重新配置Log4j; 例如,编写一个监听器来捕获a ContextStartedEvent,Appender从上下文中获取所有类型的bean,并将它们添加到Log4j配置中.这也可以让你创建你的appender作为bean,但有点避免单身麻烦.