背景:nacos需要引入flyway版本进行sql管理,同时还需要支持各种国产数据库得适配。
查阅资料能找到得参考连接:nacos2.0引入flyway管理数据库脚本_nacos flyway-CSDN博客
基于这篇文章得思路进行一点小的修改。
@Component public class CustomFlywayBeanDefinition implements BeanDefinitionRegistryPostProcessor, EnvironmentAware { private Environment environment; private static final String FLYWAY_RESTORE_STATE = "FLYWAY_RESTORE_STATE"; @Override public void setEnvironment(Environment environment) { this.environment = environment; } /** * properties配置当中数据源的参数名称 */ private static final String DB_URL_0 = "db.url.0"; private static final String DB_USER_0 = "db.user.0"; private static final String DB_PASSWORD_0 = "db.password.0"; private static final String FLYWAY_ENABLED = "spring.flyway.enabled"; private static final String DRIVER_NAME = "db.jdbcDriverName"; private static final String DB_SCHEMA = "db.schema"; private static final String FLYWAY_DB = "FLYWAY_DB"; // 注意这里注入的不是Environment @Bean public DataSource nacosDataSource(ConfigurableEnvironment env) { DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create(); dataSourceBuilder.driverClassName(env.getProperty(DRIVER_NAME)); final String schemaName = env.getProperty(DB_SCHEMA); //在url当中拼接schema if (StringUtils.isEmpty(schemaName)) { dataSourceBuilder.url(env.getProperty(DB_URL_0)); } else { final String dbUrl = env.getProperty(DB_URL_0); dataSourceBuilder.url(dbUrl + (dbUrl.contains("?") ? "¤tSchema=" : "?currentSchema=") + schemaName); } dataSourceBuilder.username(env.getProperty(DB_USER_0)); dataSourceBuilder.password(env.getProperty(DB_PASSWORD_0)); // TODO 适配其他DB类型 dataSourceBuilder.type(HikariDataSource.class); return dataSourceBuilder.build(); } /** * 外部数据持久化创建,依赖flyway自动创建状态 * * @param beanDefinitionRegistry * @throws BeansException */ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { ConfigurableEnvironment confEnv = (ConfigurableEnvironment) environment; if (!"true".equalsIgnoreCase(confEnv.getProperty(FLYWAY_ENABLED))) { return; } String flywayDbType = confEnv.getProperty(FLYWAY_DB); boolean restoreOriginalState = safeString2Boolean(environment.getProperty(FLYWAY_RESTORE_STATE), true); FlywayExternalDataManager.getInstance().initExternalParams(flywayDbType, confEnv.getProperty(DB_USER_0), confEnv.getProperty(DB_PASSWORD_0), restoreOriginalState); String flywayInitBeanName = "flywayInitializer"; String[] lazyLoadBeanNames = {"externalStoragePersistServiceImpl", "externalHistoryConfigInfoPersistServiceImpl"}; Arrays.stream(lazyLoadBeanNames).forEach(lazyBeanName -> { if (beanDefinitionRegistry.containsBeanDefinition(lazyBeanName)) { BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(lazyBeanName); String[] oldDeps = beanDefinition.getDependsOn(); if (oldDeps != null) { int len = oldDeps.length; String[] deps = new String[len + 1]; System.arraycopy(oldDeps, 0, deps, 0, len); deps[deps.length - 1] = flywayInitBeanName; beanDefinition.setDependsOn(deps); } else { beanDefinition.setDependsOn(flywayInitBeanName); } } }); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { } /** * 字符串转换为boolean 类型 * * @param originalValue 原始值 * @param defaultValue 默认值 * @return */ private boolean safeString2Boolean(String originalValue, boolean defaultValue) { if (StringUtils.isEmpty(originalValue)) { return defaultValue; } return Boolean.parseBoolean(originalValue); } }