Spring Custom DataSource Bean с Flyway создается дважды - PullRequest
0 голосов
/ 04 мая 2020

Для поддержки нескольких и разных источников данных в одном большом контексте приложения Spring, я реализовал генерацию соответствующего компонента DataSource в каждом модуле вручную.

Но до сих пор у меня проблема в том, что DataSource бин генерируется дважды, и далее миграция Flyway вызывается дважды. Я добавил соответствующий комментарий в коде ниже, чтобы обозначить места, которые вызываются дважды.

Я думаю, что это как-то связано с ComponentScan и / или Конфигурацией. Я также пытался пометить Бины в конфигурации DataSource как @Primary, но безрезультатно.

ModuleApplication

@SpringBootApplication
public class Module1Application {
    public static void main(String[] args) {
        new SpringApplicationBuilder(Module1Application.class)
                .run(args);
    }
}

Module1 Config

@SpringBootConfiguration
@ComponentScan(basePackages = {"com.example.module1"})
@PropertySource("module1.properties")
@EnableTransactionManagement
@EnableConfigurationProperties({Module1DataSourceConfig.class})    
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class Module1Config {

    // some other beans
}

Module1DataSourceConfig

@ConfigurationProperties(prefix = "module1.datasource")
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "module1EntityManagerFactory",
        transactionManagerRef = "module1TransactionManager",
        basePackages = "com.example.module1.repository")
@RequiredArgsConstructor
public class Module1DataSourceConfig extends HikariConfig {

    @Bean(name = "module1DataSource")
    public DataSource dataSource() {
         // Gets invoked twice
        return new HikariDataSource(this);
    }

    @Bean(name = "modul1EntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean modul1EntityManagerFactory(@Qualifier("module1DataSource") final DataSource dataSource) {
        final LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
        entityManagerFactoryBean.setJpaVendorAdapter(this.jpaHibernateVendorAdapter());
        entityManagerFactoryBean.setDataSource(dataSource);
        entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class);
        entityManagerFactoryBean.setPersistenceUnitName("module1");
        entityManagerFactoryBean.setPackagesToScan("com.example.module1.entities");
        entityManagerFactoryBean.setJpaProperties(this.hibernateProperties());
        entityManagerFactoryBean.afterPropertiesSet();
        return entityManagerFactoryBean;
    }

    @Bean(name = "module1TransactionManager")
    public PlatformTransactionManager module1TransactionManager(
            @Qualifier("module1EntityManagerFactory") final EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

    private HibernateJpaVendorAdapter jpaHibernateVendorAdapter() {
       // return vendor
    }

    private Properties hibernateProperties() {
        // return props.
    }

    @Bean(name="module1Flyway", initMethod = "migrate")
    @ConditionalOnProperty(prefix = "moudle1.flyway", name = "enabled", matchIfMissing = true)
    public Flyway flyway(@Qualifier("module1DataSource") final DataSource dataSource, final Modul1flywayConfig module1FlywayConfig) {       
        // Gets invoked twice
        return Flyway
                .configure()
                .locations(module1FlywayConfig.getLocations())
                .dataSource(dataSource)
                .load();
    }

    @Bean
    FlywayMigrationInitializer flywayInitializerModul1(@Qualifier("module1Flyway") Flyway flyway) {
        // Gets invoked twice
        return new FlywayMigrationInitializer(flyway, null);
    }
}

Module1FlywayConfig

@Configuration
@ConfigurationProperties(prefix = "module1.flyway")
@Data
public class Module1FlywayConfig {
    private boolean placeholderReplacement;
    private boolean enabled;
    private String[] locations;
}
...