前の記事(SpringBootプロジェクトプロファイルは動的にリンクを追加する方法を、説明しリフレッシュしてくださいケース)、アプリケーション・サービスへの通知メカニズム春の雲バスの動的更新設定を使用する方法について説明し、この記事では、再起動せずにどのようにマイクロサービスについて説明しますデータベース接続パラメータを、動的に変化します。
Mysqlの例えば、どのようにそれはマイクロサービス、変更、パスワード、またはリンクアドレスを再起動することなく、のパラメータを接続するには?MySQLのデータソースとのSessionFactoryは通常、ブート時に単利としてインスタンスので、直接更新するためにパラメータを変更すると再構築の効果を再生することはできません、動的な変更を達成するために、次のように、あなたは、datasouceおよび動的置換たBeanFactoryのSessionFactoryの例に持っていますいくつかの側面を考慮する必要があります。
- パスワード変更通知アプリケーション・サービスの後
- 最新のアプリケーションサービスの接続情報を取得し、比較します
- アプリケーションサービスは、現在のSQLSESSIONをリリース
- データソースとsqlsessionFactoryを再構築
- 新しいインスタンスが登録された豆のコンテキストにフラッシュされます
現在の状況は、いくつかのことが本当来た休息、最初の問題に加えて、バスリフレッシュによって達成することができるということです。まず第一に考えることができ、イベントが最新の設定を取得するために、リスナーを介してRefreshScopeRefreshedEventを聞き、その後、データソースとのSessionFactoryを再構築できるかどうか、春のイベントメカニズムのですか?途中、私が試して作られた、ここでは完全なテストコードは次のとおりです。
@Component
public class AppConfigChangeListener implements ApplicationListener<RefreshScopeRefreshedEvent> {
private static Log logger = LogFactory.getLog(AppConfigChangeListener.class);
@Resource
private DataSourceProperties dataSourceProperties;
@Value("classpath*:mybatis/mapper/**/*.xml")
private org.springframework.core.io.Resource[] mapperLocations;
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent applicationEvent) {
logger.info("refresh scope: " + JSON.toJSONString(dataSourceProperties));
DataSource dataSource = (DataSource) ApplicationContextUtils.getBean("dataSource");
if (dataSource != null && HikariDataSource.class.isInstance(dataSource)) {
HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) ApplicationContextUtils.getBean("sqlSessionFactory");
if (sqlSessionFactory != null && connectParamChanged(hikariDataSource, dataSourceProperties)) {
if (SqlSessionManager.class.isInstance(sqlSessionFactory)) {
((SqlSessionManager) sqlSessionFactory).close();
}
rebuildSqlSessionFactory(dataSourceProperties);
}
}
}
private void rebuildSqlSessionFactory(DataSourceProperties dataSourceProperties) {
try {
DataSource dataSource = dataSource(dataSourceProperties);
SqlSessionFactory sqlSessionFactory = sqlSessionFactory(dataSource, mapperLocations);
ApplicationContextUtils.refreshBean("dataSource", dataSource);
ApplicationContextUtils.refreshBean("sqlSessionFactory", sqlSessionFactory);
DataSource newDS = (DataSource) ApplicationContextUtils.getBean("dataSource");
SqlSessionFactory newSSF = (SqlSessionFactory) ApplicationContextUtils.getBean("sqlSessionFactory");
System.out.println("....");
} catch (Exception e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
private boolean connectParamChanged(HikariDataSource dataSource, DataSourceProperties dataSourceProperties) {
return !StringUtils.equals(dataSource.getUsername(), dataSourceProperties.getUsername()) ||
!StringUtils.equals(dataSource.getPassword(), dataSourceProperties.getPassword()) ||
!StringUtils.equals(dataSource.getJdbcUrl(), dataSourceProperties.getUrl());
}
public DataSource dataSource(DataSourceProperties dataSourceProperties) {
return DataSourceBuilder.create()
.type(HikariDataSource.class).driverClassName(dataSourceProperties.getDriverClassName())
.url(dataSourceProperties.getUrl()).username(dataSourceProperties.getUsername())
.password(dataSourceProperties.getPassword())
.build();
}
public SqlSessionFactory sqlSessionFactory(DataSource dataSource, org.springframework.core.io.Resource[] mapperLocations) throws Exception {
CustomSqlSessionFactoryBean sqlSessionFactoryBean = new CustomSqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setMapperLocations(mapperLocations);
sqlSessionFactoryBean.setTypeAliasesPackage(ApplicationConsts.BASE_PACKAGE);
sqlSessionFactoryBean.setTypeAliasesSuperType(PersistenceEntity.class);
PagerCountInterceptor pagerCountInterceptor = new PagerCountInterceptor();
pagerCountInterceptor.setProperties(new Properties());
Interceptor[] plugins = new Interceptor[]{
new PagerInterceptor(),
pagerCountInterceptor,
new EntityUpdateInterceptor()
};
sqlSessionFactoryBean.setPlugins(plugins);
return sqlSessionFactoryBean.getObject();
}
}
下記の区分の説明:
@Resource
private DataSourceProperties dataSourceProperties;
@Value("classpath*:mybatis/mapper/**/*.xml")
private org.springframework.core.io.Resource[] mapperLocations;
dataSourcePropertiesパラメータは、データソースを構築するために必要とされる、データベースの構成属性は、特定のオブジェクトです。
mapperLocationsパラメータを調整する必要がない一般sqlSessionFactoryを構築することが必要です。
@Override
public void onApplicationEvent(RefreshScopeRefreshedEvent applicationEvent) {
logger.info("refresh scope: " + JSON.toJSONString(dataSourceProperties));
DataSource dataSource = (DataSource) ApplicationContextUtils.getBean("dataSource");
if (dataSource != null && HikariDataSource.class.isInstance(dataSource)) {
HikariDataSource hikariDataSource = (HikariDataSource) dataSource;
SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) ApplicationContextUtils.getBean("sqlSessionFactory");
if (sqlSessionFactory != null && connectParamChanged(hikariDataSource, dataSourceProperties)) {
if (SqlSessionManager.class.isInstance(sqlSessionFactory)) {
((SqlSessionManager) sqlSessionFactory).close();
}
rebuildSqlSessionFactory(dataSourceProperties);
}
}
}
我々は、ユーザー名やパスワードを見つけるか、またはURIが変更された場合、データソースとsqlSessionFactoryを更新した場合、この方法では、configbusにコアロジック、および事後テストリフレッシュイベントです。
private boolean connectParamChanged(HikariDataSource dataSource, DataSourceProperties dataSourceProperties) {
return !StringUtils.equals(dataSource.getUsername(), dataSourceProperties.getUsername()) ||
!StringUtils.equals(dataSource.getPassword(), dataSourceProperties.getPassword()) ||
!StringUtils.equals(dataSource.getJdbcUrl(), dataSourceProperties.getUrl());
}
最新datasourceProperties属性と属性データソースBeanプールに基づいて、シンプルなソリューションを比較してください。注釈を追加するために必要な時にリフレッシュ状態、@RefreshScope DataSourceProperties属性クラスは自動的に自動的にインポートされます。
private void rebuildSqlSessionFactory(DataSourceProperties dataSourceProperties) {
try {
DataSource dataSource = dataSource(dataSourceProperties);
SqlSessionFactory sqlSessionFactory = sqlSessionFactory(dataSource, mapperLocations);
ApplicationContextUtils.refreshBean("dataSource", dataSource);
ApplicationContextUtils.refreshBean("sqlSessionFactory", sqlSessionFactory);
DataSource newDS = (DataSource) ApplicationContextUtils.getBean("dataSource");
SqlSessionFactory newSSF = (SqlSessionFactory) ApplicationContextUtils.getBean("sqlSessionFactory");
System.out.println("....");
} catch (Exception e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
}
プロセスは重要なプロセスである再構築、コアがrefreshBeanです。
public static void refreshBean(String name, Object bean) {
if (getContext() != null && ConfigurableApplicationContext.class.isInstance(getContext())) {
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) getContext();
ConfigurableListableBeanFactory beanFactory = configurableApplicationContext.getBeanFactory();
if (DefaultListableBeanFactory.class.isInstance(beanFactory)) {
((DefaultListableBeanFactory) beanFactory).destroySingleton(name);
beanFactory.registerSingleton(name, bean);
} else {
beanFactory.destroyScopedBean(name);
}
}
}
refreshBean論理は単純ですが、再登録、シングルトンオブジェクトたBeanFactoryを削除します。
買収は、限り、あなたはApplicationContextAware注入を達成することができますよう、コンテキストのアプローチを説明していません。
次のステップでは、アプリケーションを起動した後、照会サービスを呼び出し、テストされます。あなたのパスワード、バスリフレッシュを変更し、追跡要求し、あなたが効果を見ることができます。