我正在尝试设置从HOCON语法.conf
文件加载的自定义@ConfigurationProperties
类。
我有一个用@PropertySource(factory=TypesafePropertySourceFactory.class, value = "classpath:app.conf")
注释的类
@Configuration
@ConfigurationProperties(value = "app.server")
@PropertySource(factory = TypesafePropertySourceFactory.class, value = "classpath:app.conf")
public class ServerProperties {
public int port;
}
和一个简单的测试类:
@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class SomeTest {
@Test
public void someCoolTest() {/* ... */}
// ...
}
当我运行我的junit测试运行程序时,我得到以下错误:
Caused by: com.typesafe.config.ConfigException$BadPath: path parameter: Invalid path 'spring.info.build.location:classpath:META-INF/build-info.properties': Token not allowed in path expression: ':' (you can double-quote this token if you really want it here)
at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:155) ~[config-1.4.0.jar:1.4.0]
at com.typesafe.config.impl.PathParser.parsePathExpression(PathParser.java:74) ~[config-1.4.0.jar:1.4.0]
at com.typesafe.config.impl.PathParser.parsePath(PathParser.java:61) ~[config-1.4.0.jar:1.4.0]
...
如果我取消对ServerProperties
类上的@PropertySource行的注释,则测试将正常进行。我觉得奇怪的是,我的自定义PropertySourceFactory
妨碍了默认的.properties
文件解析过程。
PropertySource和Factory类
// TypesafeConfigPropertySource.java
import com.typesafe.config.Config;
import org.springframework.core.env.PropertySource;
public class TypesafeConfigPropertySource extends PropertySource<Config> {
public TypesafeConfigPropertySource(String name, Config source) {
super(name, source);
}
@Override
public Object getProperty(String path) {
if (source.hasPath(path)) {
return source.getAnyRef(path);
}
return null;
}
}
// TypesafePropertySourceFactory.java
import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import java.io.IOException;
import java.util.Objects;
public class TypesafePropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
Config config = ConfigFactory.load(Objects.requireNonNull(resource.getResource().getFilename())).resolve();
String safeName = name == null ? "typeSafe" : name;
return new TypesafeConfigPropertySource(safeName, config);
}
}
我是否遗漏了配置自定义属性资源工厂的一些基本内容,或者这是一个错误?
版本
- 弹簧套2.3.4
- Junit Jupiter 5.6.2
也许您也可以使用ContextInitializer来解决它,如这里的答案所建议的:
由Typesafe Config 支持的Spring环境
TL;DR
如果无法在自定义impl中处理path
,则返回null
public class TypesafeConfigPropertySource extends PropertySource<Config> {
// ...
@Override
public Object getProperty(String path) {
try {
if (source.hasPath(path)) {
return source.getAnyRef(path);
}
} catch(ConfigException.BadPath ignore) {
}
return null;
}
// ...
}
解释
我正在进行有根据的猜测,但在功能上,这似乎得到了代码行为的支持
这里最有可能的情况是,解决顺序将在任何默认实现之前考虑我们的自定义实现。在我们的实现中使用的方法将与包含":"以及";
我只是简单地包装BadPath
异常以捕捉任何问题,然后返回null表示不匹配。