如何在 Mongock 变更日志中注入没有接口的 bean

How to inject beans without interface in Mongock changelogs

我正在将 spring 启动应用程序从 2.2.2 迁移到 2.2.3。我还将 mongock 升级到 4.1.16,因为目前使用的版本 2.0.2 不再兼容。

我有这个更新日志,它在 2.0.2 中运行良好,但在 4.1.16 中运行良好:

    @ChangeSet(order = "001", id = "initDatabaseParametre", author = "xxxxx")
    public void initDatabaseParametre(ParametreManager parametreManager, ObjectMapper mapper) throws IOException 
        // someting
    }

对于 4.1.16 我有这个异常,因为 ObjectMapper 不是接口 (com.fasterxml.jackson.databind.ObjectMapper) :

io.changock.migration.api.exception.ChangockException: Error in method[ChangelogInitDatabase.initDatabaseParametre] : Parameter of type [ObjectMapper] must be an interface
        at io.changock.runner.core.MigrationExecutor.processExceptionOnChangeSetExecution(MigrationExecutor.java:179)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:97)
        at io.changock.runner.core.MigrationExecutor.lambda$processSingleChangeLog(MigrationExecutor.java:89)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:75)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeLog(MigrationExecutor.java:89)
        at io.changock.runner.core.MigrationExecutor.lambda$processAllChangeLogs(MigrationExecutor.java:83)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:75)
        at io.changock.runner.core.MigrationExecutor.processAllChangeLogs(MigrationExecutor.java:83)
        at io.changock.runner.core.MigrationExecutor.lambda$executeMigration[=11=](MigrationExecutor.java:64)
        at com.github.cloudyrock.mongock.driver.mongodb.springdata.v3.SpringDataMongo3Driver.executeInTransaction(SpringDataMongo3Driver.java:108)
        at io.changock.runner.core.MigrationExecutor.executeInTransactionIfStrategyOrUsualIfNot(MigrationExecutor.java:73)
        at io.changock.runner.core.MigrationExecutor.executeMigration(MigrationExecutor.java:64)
        at io.changock.runner.spring.v5.core.SpringMigrationExecutor.executeMigration(SpringMigrationExecutor.java:38)
        at io.changock.runner.core.ChangockBase.execute(ChangockBase.java:44)
        at io.changock.runner.spring.v5.ChangockSpringBuilderBase$ChangockSpringApplicationRunner.run(ChangockSpringBuilderBase.java:110)
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:786)
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
        at com.myproject.MyApplication.main(MyApplication.java:23)
Caused by: io.changock.migration.api.exception.ChangockException: Parameter of type [ObjectMapper] must be an interface
        at io.changock.runner.core.DependencyManagerWithContext.getDependency(DependencyManagerWithContext.java:42)
        at io.changock.runner.core.MigrationExecutor.getParameter(MigrationExecutor.java:165)
        at io.changock.runner.core.MigrationExecutor.executeChangeSetMethod(MigrationExecutor.java:155)
        at io.changock.runner.core.MigrationExecutor.executeAndLogChangeSet(MigrationExecutor.java:111)
        at io.changock.runner.spring.v5.core.SpringMigrationExecutor.executeAndLogChangeSet(SpringMigrationExecutor.java:44)
        at io.changock.runner.core.MigrationExecutor.processSingleChangeSet(MigrationExecutor.java:95)
        ... 19 common frames omitted

我的更新日志中需要 ObjectMapper,因为我的迁移过程读取 json 个文件。

如您在 Using custom beans in changeSet methods section, in the Mongock's documentation 中所见,您在 changeSet 中使用的自定义 beans 必须是接口。

Here有一些解释。

但是,您可以告诉 Mongock 您不想要那样。侵入性较小的机制是向您的 changeSet 参数添加注释 @NonLockGuarded,如 this section.

中所述

该方法的缺点是每次在所有变更集中使用该 bean 时都需要添加注释。也许更方便但也更具侵入性的方法是向 bean 的类型添加相同的注释,在本例中为 ObjectMapper,如 this section.

中所述

因为我假设它是杰克逊的 ObjectMapper,而不是所有这些,您可以将 SpringContext 作为参数并从中获取 ObjectMapper bean,但它并不理想,原因很明显(这适用于任何类型的 bean)