如果使用了不推荐的属性,则会导致构建失败

简介

有一个方便的库叫做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());
    }
}
bannerAds