如果使用了不推荐的属性,则会导致构建失败
简介
有一个方便的库叫做spring-boot-properties-migrator可用于检测不推荐的属性,但最好的情况下我们想导致构建失败…!
→ 虽然方法有些强硬,但总算实现了,我先将其记下来作为备忘录。
spring-boot-properties-migrator是什么?
这是一个能够检测非推荐的属性,并通过警告日志和错误日志来通知我们的库。
(它应该也会处理属性的重命名)
主要是PropertiesMigrationListener正在努力工作。
准备好
當撰寫這篇文章時,我手頭上使用的原始碼的 build.gradle 摘錄如下:
我撰寫這篇文章的時候,手上的原始碼內的 build.gradle 摘錄如下:
在寫這篇文章時,我手上的原始碼中的 build.gradle 摘要如下:
plugins {
id 'org.springframework.boot' version "2.5.0"
id 'io.spring.dependency-management' version "1.0.11.RELEASE"
id 'java'
id 'com.github.ben-manes.versions' version "0.36.0"
}
...
dependencies {
...
testRuntimeOnly("org.springframework.boot:spring-boot-properties-migrator")
testCompileOnly("org.springframework.boot:spring-boot-properties-migrator")
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
导致构建失败
PropertiesMigrationListener是一个只有日志输出,而没有提取报告内容的方法的类,因此我们需要自己创建一个包装类来处理。
那个实施方案在这里。
@Slf4j
public class PropertiesMigrationListenerWrapper
implements ApplicationListener<SpringApplicationEvent> {
private PropertiesMigrationReport report;
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
log.info("event class: {}", event.getClass());
if (event instanceof ApplicationStartedEvent) {
onApplicationPreparedEvent((ApplicationStartedEvent) event);
}
}
@EventListener
public void onApplicationPreparedEvent(ApplicationStartedEvent event) {
ConfigurationMetadataRepository repository = loadRepository();
PropertiesMigrationReporter reporter = new PropertiesMigrationReporter(repository,
event.getApplicationContext().getEnvironment());
this.report = reporter.getReport();
}
private ConfigurationMetadataRepository loadRepository() {
try {
return loadRepository(ConfigurationMetadataRepositoryJsonBuilder.create());
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load metadata", ex);
}
}
private ConfigurationMetadataRepository loadRepository(ConfigurationMetadataRepositoryJsonBuilder builder)
throws IOException {
Resource[] resources = new PathMatchingResourcePatternResolver()
.getResources("classpath*:/META-INF/spring-configuration-metadata.json");
for (Resource resource : resources) {
try (InputStream inputStream = resource.getInputStream()) {
builder.withJsonResource(inputStream);
}
}
return builder.build();
}
// 非推奨なpropertyが存在するか真偽値を返す
public boolean existsDeprecatedProperty() {
var result = false;
String warningReport = this.report.getWarningReport();
if (warningReport != null) {
log.warn(warningReport);
result = true;
}
String errorReport = this.report.getErrorReport();
if (errorReport != null) {
log.error(errorReport);
result = false;
}
return result;
}
}
这几乎是PropertiesMigrationListener的复制粘贴,但为了测试验证,我准备了existsDeprecatedProperty()。
另外,package是固定的org.springframework.boot.context.properties.migrator。
(因为使用类是package private类…)
是的,这就是我所说的强制的原因。
有了Wrapper类之后,我们将其注册为Bean,以便监听SpringApplicationEvent事件。
@Configuration
public class TestAutoConfiguration {
@Bean
public PropertiesMigrationListenerWrapper propertiesMigrationListenerWrapper() {
return new PropertiesMigrationListenerWrapper();
}
}
最後是測試類。
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {Application.class, TestAutoConfiguration.class})
class PropertyMigrateTest {
@Autowired
private PropertiesMigrationListenerWrapper migrationListener;
@Test
void test() {
assertFalse(migrationListener.existsDeprecatedProperty());
}
}