繁体   English   中英

如何在运行时创建数据源 bean 而不会在 Spring 中崩溃应用程序?

[英]How to create datasource bean at runtime without crashing app in Spring?

我正在连接到多个数据源,但有时某些数据源可能处于脱机状态,当时我在应用程序上遇到错误,并且应用程序在启动时失败。

我想在启动时跳过数据源配置......我尝试了几种方法,添加

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 

到 application.properties,我也尝试添加

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})

到主要的 class 但它仍然尝试配置数据源。

我还尝试在所有方法和构造函数上使用@Lazy 注释,如下所示,但在创建 fooEntityManagerFactory 时仍然出错

@Lazy
@Configuration
@EnableJpaRepositories(basePackages = "com.heyo.tayo.repository.foo", entityManagerFactoryRef = "fooEntityManagerFactory", transactionManagerRef = "fooTransactionManager")
public class PersistencefooConfiguration {

    @Autowired
    private DbContextHolder dbContextHolder;

    @Lazy
    @Bean
    @ConfigurationProperties("tay.datasource.foo")
    public DataSourceProperties fooDataSourceProperties() {
        return new DataSourceProperties();
    }

    @Lazy
    @Bean
    @ConfigurationProperties("tay.datasource.foo.configuration")
    public DataSource fooDataSource() {
        DataSource dataSource = fooDataSourceProperties().initializeDataSourceBuilder()
                    .type(BasicDataSource.class).build();
        dbContextHolder.addNewAvailableDbType(DbTypeEnum.foo);

        return dataSource;
    }

    @Lazy
    @Bean(name = "fooEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean fooEntityManagerFactory(
            EntityManagerFactoryBuilder builder) {

//THE CODE IS FAILING AT BELOW RETURN CASE

        return builder
                .dataSource(fooDataSource())
                .packages("com.heyo.tayo.model.foo")
                .build();
    }

    @Lazy
    @Bean
    public PlatformTransactionManager fooTransactionManager(
            final @Qualifier("fooEntityManagerFactory") LocalContainerEntityManagerFactoryBean fooEntityManagerFactory) {
        return new JpaTransactionManager(fooEntityManagerFactory.getObject());
    }

}

对于不同数据源的不同配置,我有多个像上面这样的类,我将它们添加到数据源 Bean 的可用 dbs static 列表中。

这是我的 dbadapter 工厂 class。

这是我创建相应数据库适配器的 dbAdaptor 工厂

@Service
public class DbAdapterFactory {

    @Autowired
    private BeanFactory beanFactory;

    @Autowired
    private DbContextHolder dbContextHolder;

    public DBAdapter dbAdapter(){

        DbTypeEnum currentDb = dbContextHolder.getCurrentDb();
        DBAdapter dbAdapter = null;

        if(currentDb == DbTypeEnum.FOODB) {
            dbAdapter = beanFactory.getBean(foodbadaptor.class);
        } else {
            dbAdapter = beanFactory.getBean(koodbadaptor.class);
        }

        return dbAdapter;
    }

这是 db 上下文持有者,它可以进行设置默认数据库或获取当前数据库等操作:

@Component
public class DbContextHolder {

    private DbTypeEnum dbType = DbTypeEnum.FOODB;
    private Set<DbTypeEnum> availableDbTypes = new HashSet<>();

    public void setCurrentDb(DbTypeEnum dbType) {
        this.dbType = dbType;
    }

    public DbTypeEnum getCurrentDb() {
        return this.dbType;
    }

    public List<DbTypeEnum> getAvailableDbTypes() {
        return new ArrayList<>(availableDbTypes);
    }

    public void addNewAvailableDbType(DbTypeEnum dbTypeEnum) {
        availableDbTypes.add(dbTypeEnum);
    }
}

我做了所有@Lazy 或尝试@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})但仍然有一些东西正在调用创建bean并出现错误并且应用程序正在关闭。 我想在 try-catch 块中使用该配置和数据源,并且不要在运行时停止应用程序。 我怎样才能实现这一点,或者我在配置或注释中缺少什么?

我相信您可以简单地添加您的应用程序属性

spring.sql.init.continue-on-error=true

根据 Spring Boot 2.5.5 用户指南:

https://docs.spring.io/spring-boot/docs/2.5.5/reference/htmlsingle/#howto-initialize-a-database-using-spring-jdbc

Spring 引导启用其基于脚本的数据库初始化程序的快速故障功能。 如果脚本导致异常,应用程序将无法启动。 您可以通过设置 spring.sql.init.continue-on-error 来调整该行为。

根据您的 spring 引导版本,该属性将被命名为

spring.sql.init.continue-on-error

或之前 Spring 启动 2.5

spring.datasource.continue-on-error

这太愚蠢了,但我通过在 application.properties 中添加以下内容解决了这个问题。

spring.jpa.database=sql_server

我不知道为什么我需要在属性文件中明确指定,但问题已经解决。 我会寻找它

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM