我正在使用 spring 将一个类注入到我的 PropertyDefiner 实现中,该类将用于帮助在 logback.xml 文件中设置一些属性(通过动态属性加载)。
我很想在配置 logback 之前加载和实例化这个类。关于如何做到这一点的任何想法?
我正在使用 spring 将一个类注入到我的 PropertyDefiner 实现中,该类将用于帮助在 logback.xml 文件中设置一些属性(通过动态属性加载)。
我很想在配置 logback 之前加载和实例化这个类。关于如何做到这一点的任何想法?
我的解决方案导致没有实现 PropertyDefiner。最初的问题变成了没有来自 spring 的应用程序上下文来设置动态属性的问题。我不确定为什么,但是在应用程序上下文可用之前,稍后的侦听器(在 Spring 侦听器之后)中的代码会被调用(调用 LoggerFactory 调用)。我尝试了很多东西,直到我开始寻找一种不同的方法。
我没有使用动态属性,而是创建了一个侦听器(在服务器启动时调用),然后以编程方式使用我想要的属性(通过 createAdminNotifyAppender)设置我的 appender。
@Override
public void contextInitialized(ServletContextEvent arg0)
{
//Set up the property reader to pull the correct properties
ServletContext context = arg0.getServletContext();
ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(context);
propReader = (AppConfigPropertiesReader)appContext.getBean("propertySourcesPlaceholder");
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
createAdminNotifyAppender(lc, propReader);
}
createAdminNotify 方法只是设置一个 appender 并将其添加到日志记录上下文中。(如果你真的感兴趣,你可以在这个线程上看到该方法的实现)。
现在我有一个单独的模块化监听器,我可以将它添加到其他使用 logback 的应用程序中,但可能具有不同的属性。这些属性是从数据库中提取的,也可能因环境而异。
如果您在 Spring 中使用注解,可以通过将要注入的类(即依赖项)标记为 @Component 然后在 PropertyDefiner 实现中使用 @Autowired 来方便地执行此操作。这确保了第一个类将首先被实例化。http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch04s12.html
您需要的任何其他初始化都可以使用实例初始化程序块http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html来实现
我不知道目前(2012-07)这是否可以优雅地完成。但是,在LOGBACK-719中已请求支持注入。
如果您的 bean 工厂实现 AutowireCapableBeanFactory,给定 Spring Applicaton 上下文,您可以调用autowireBean(Object existingBean)来自动装配 bean。这是一个暂定的实现:
class Your.PropertyDefiner implements PropertyDefiner, LifeCycle {
@Autowired
@Qualifier("myKey")
String myKey;
public void start() {
ApplicationContext appContext = ... somehow get the spring app context
AutowireCapableBeanFactory factory = appContext.getAutowireCapableBeanFactory();
factory.autowireBean(this); // declare victory
}
}
仅当您的 PropertyDefiner 实现LifeCycle接口start()
时才会调用该方法。此外,您需要 logback 版本 1.0.7 或更高版本。早期版本不调用.start()