当使用Spring Boot或仅使用普通的Spring Framework时,可能要延迟应用程序的启动,直到可以与数据库建立正确的连接为止。当使用容器技术(例如Docker)时,情况可能更是如此。
DatabaseStartupValidator 会延迟应用程序的进一步启动,直到可以建立与数据库的连接为止。默认情况下,它将每秒尝试连接到数据库,并仅捕获异常。它将尝试60秒,此后如果无法建立连接,则失败(所有这些属性都是可配置的)。
要使用它,只需声明一个bean并注入数据源。您定义一个验证查询(从Spring 5.3开始,它将isValid默认使用JDBC 4 方法!)。Spring Boot附带了一个方便的 枚举 ,该 枚举 已经包含针对一系列受支持数据库的默认验证查询(由Spring Boot Actuator中的运行状况检查使用)。
@SpringBootApplication <b>public</b> <b>class</b> DatabaseUpApplication { <b>public</b> <b>static</b> <b>void</b> main(String[] args) { SpringApplication.run(DatabaseUpApplication.<b>class</b>, args); } @Bean <b>public</b> DatabaseStartupValidator databaseStartupValidator(DataSource dataSource) { <b>var</b> dsv = <b>new</b> DatabaseStartupValidator(); dsv.setDataSource(dataSource); dsv.setValidationQuery(DatabaseDriver.POSTGRESQL.getValidationQuery()); <b>return</b> dsv; } }
但是,仅定义此bean可能还不够,需要更多配置。有许多依赖DataSource 的beans如EntityManagerFactory,Flyway 或 JdbcTemplate ,需要手工增加@DependsOn在这些@Bean方法上:可通过Spring Boot进行一些自动配置,也可以使用a BeanFactoryPostProcessor 来修改bean
@Bean <b>public</b> <b>static</b> BeanFactoryPostProcessor dependsOnPostProcessor() { <b>return</b> bf -> { <font><i>// Let beans that need the database depend on the DatabaseStartupValidator</i></font><font> </font><font><i>// like the JPA EntityManagerFactory or Flyway</i></font><font> String[] flyway = bf.getBeanNamesForType(Flyway.<b>class</b>); Stream.of(flyway) .map(bf::getBeanDefinition) .forEach(it -> it.setDependsOn(</font><font>"databaseStartupValidator"</font><font>)); String[] jpa = bf.getBeanNamesForType(EntityManagerFactory.<b>class</b>); Stream.of(jpa) .map(bf::getBeanDefinition) .forEach(it -> it.setDependsOn(</font><font>"databaseStartupValidator"</font><font>)); }; } </font>
这里延缓了Flyway 和 EntityManagerFactory执行,直到DatabaseStartupValidator 完全初始化。
源代码可以在 GitHub 上 找到 。