有哪些可用选项可用于在 Spring 管理的 Web 应用程序内的 Log4J Appender 中检索 Spring 管理的 bean?
我当前的构建主管在理论上有一个好主意 - 构建一个自定义 Log4J 附加程序,它接受 Spring 管理的 bean,并使用它们将错误记录到各种其他来源,而不仅仅是标准日志文件。然而,除了创建一个在启动时使用应用程序上下文初始化的单例(稍后编写代码)之外,我似乎想不出在 Log4J 附加程序中检索 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 一样通过依赖注入进行设置 - bean 引用永远不会改变,无论初始化了多少个appender。有什么想法吗?
My current build lead has a great idea in theory - construct a custom Log4J appender that takes in Spring-managed beans and uses them to log errors to various other sources than just the standard log file. However, other than creating a singleton initialized at startup with the application context (code in just a moment), I can't seem to think of any other options of retrieving a Spring managed bean in a Log4J appender.
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;
}
}
Ideally, these properties could be set just like beans in Spring via dependency injection - the bean references will never change, no matter how many appenders are initialized. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于 log4j 必须在 Spring 之前初始化,因此您将遇到 boostrap 问题。无论您是否使用 自定义配置 或 Log4j 的标准初始值设定项,它必须在应用程序上下文之前启动。
现在,理论上您可以使自定义附加程序“延迟”初始化自身(通过上面建议的方法或使附加程序本身成为“半”单例 - 例如附加程序类有一个静态实例字段,由
afterPropertiesSet 填充()
方法;这样你就可以在Spring中将appender本身创建为bean),但它看起来有点混乱和不一致。另一种方法是在 Spring 上下文初始化后动态重新配置 Log4j;例如编写一个 监听器捕获
ContextStartedEvent
,从上下文中获取Appender
类型的所有bean并将它们添加到Log4j配置中。这也将允许你将你的appender创建为bean,但在某种程度上避免单例混乱。You're going to have a boostrap problem since log4j has to be initialized before Spring. Whether you're using a custom configuration or Log4j's standard initializer, it has to be up before application context is.
Now, you could in theory make your custom appenders "lazily" initialize themselves (either via approach you've suggested above or by making appenders themselves "semi" singletons - e.g. appender class has a static instance field which gets populated by
afterPropertiesSet()
method; that way you can create appender itself as bean within Spring) but it seems somewhat messy and inconsistent.Another approach is to dynamically reconfigure Log4j once Spring context is initialized; e.g. write a listener to catch a
ContextStartedEvent
, obtain all beans of typeAppender
from the context and add them to Log4j configuration. This will also allow you to create your appenders as beans but avoid singleton mess somewhat.有点晚了,但我希望这可以帮助其他人。我在以下链接中提供的答案中记录了此问题的解决方案:
log4j - 从日志附加程序类访问 spring bean
Bit late, but I hope that this can help someone else. I've documented a solution to this issue in the answer i've provided in the following link:
log4j - Accessing spring bean from logging appender class