我正在修改使用 Spring 3.1.4 的旧项目。
我正在尝试使用 StartupListener 来配置 Logback:
public class LoggingStartupListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(LoggingStartupListener.class.getName());
@Override
public void contextInitialized(final ServletContextEvent sce) {
final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
context.reset();
final JoranConfigurator configurator = new JoranConfigurator();
final ServletContext servletContext = sce.getServletContext();
final StringBuilder filePath = new StringBuilder(100);
filePath.append(servletContext.getRealPath("/"));
filePath.append(servletContext.getInitParameter("logFileName"));
InputStream configStream = null;
try {
configStream = FileUtils.openInputStream(new File(filePath.toString()));
...
它正在从 web.xml 读取文件路径:
<context-param>
<param-name>logFileName</param-name>
<param-value>/WEB-INF/config/${spring.profiles.active}/logback.xml</param-value>
</context-param>
现在,当我运行 JUnit 测试时,我总是遇到异常:
java.io.FileNotFoundException: File '/var/folders/v7/1r3m8y8j487dqj7vmvb4n4kxcw70fj/T/tomcat-embedded-77438108580291256392.tmp/webapps/myproject/WEB-INF/config/${spring.profiles.active}/logback.xml' does not exist
at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:136)
这意味着 spring.profiles.active 属性永远不会被解析。
我尝试了各种方法:
1)我尝试在测试前设置属性:
@BeforeClass
public static void setSystemProperty() {
System.out.println("---------------------BeforeClass--------------------");
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setActiveProfiles("local");
ctx.refresh();
System.setProperty("spring.profiles.active", "local");
}
但是它不起作用,因为这个方法是在错误抛出后调用的。 (“----------BeforeClass--------------”出现在日志中错误之后很久。)
2)我尝试在测试类之前使用注释:
@ActiveProfiles(profiles = "local")
3)我尝试使用 spring-test.properties 文件设置属性:
spring.profile.active=local
并将其包含在测试上下文中:
<context:property-placeholder location="classpath:spring-test.properties"/>
-> 没有任何效果
4)我什至尝试直接在 ServletContextListener 中设置属性:
@Override
public void contextInitialized(final ServletContextEvent sce) {
System.setProperty("spring.profiles.active", "local");
...
这真的让我感到惊讶,因为这应该有效,不是吗?
我遇到这些问题是因为我使用的是旧的 Spring 版本吗?我在其他具有更高 Spring 版本的项目中从未遇到过这些问题。 或者我错过了什么?
我可以将监听器配置为稍后启动吗?或者我可以配置单元测试以在 ServletContextListener 启动之前设置系统属性吗?
或者以不同的方式初始化 logback 以避免这些问题会更好 - 但为什么它们不会出现在其他项目中?
我发现了这个,但我不知道这是否适用于我的情况: Spring-test and ServletContextListener in web.xml
它表示无法使用 Spring MVC Test 配置 ServletContextListener。它说我可以尝试用
覆盖上下文参数wac.getServletContext().setInitParameter(name, value);
但我不知道何时何地执行此操作,因为显然在初始化测试类之前已读取了 web.xml。
提前非常感谢您的任何提示
最佳答案
我使用了 logback spring 扩展而不是我们自己的实现,问题就消失了!
我使用了这个文档: https://github.com/qos-ch/logback-extensions/wiki/Spring
其特点之一是: - “使用 Spring 资源路径和系统属性占位符指定 logback.xml 位置。”
正是我所需要的。我使用的是 logback-ext-spring 版本 0.1.4。
关于java - 在 ServletContextListener 使用 web.xml 中的文件路径之前设置 JUnit 测试的系统属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39857234/