【发布时间】:2016-10-04 16:16:58
【问题描述】:
我正在修改使用 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 测试配置 ServletContextListener。它说我可以尝试用
覆盖上下文参数wac.getServletContext().setInitParameter(name, value);
但我不知道什么时候/在哪里做,因为 web.xml 显然是在初始化测试类之前读取的。
非常感谢任何提示
【问题讨论】:
-
似乎
ServletContextListener在Spring生命周期之前执行,因此spring.profiles.active没有自动解决Spring 的预期。也许您应该尝试从您的contextInitialized方法中手动获取该密钥。
标签: java spring junit servletcontextlistener spring-profiles