springboot讀寫分離開關控制

上文中http://blog.csdn.net/liunian02050328/article/details/75090297 講述了springboot環境下讀寫分離的實現方法;

項目搭建的核心是爲了給更多的用戶去使用,部分情況下是使用讀寫分離,然後可以直接用這套框架,但是部分項目因業務量比較小,不想使用讀寫分離的方案呢?修改config?是的,這個方案看起來很不錯,那麼我們就坑次坑次的修改,修改好之後正常跑起來項目,看起來是一個不錯的方案得到實施,過了幾天後項目經理說,小X,根據項目的實際需求我們還是需要用到讀寫分離的方案,但是在本地開發的環境下只有master庫,此時再次修改代碼貌似不是一個良好的解決方案了;ok,那就看下下面的方案吧,下面的是個人觀點及思路:

首先定義參數

readAndwriteKey: false   #true  false的時候代表的是不使用讀寫分離,true的時候是使用讀寫分離方案

通過參數配置,實現dev和relase環境的自由切換;

下面看下代碼部分的修改;

在設計此方案的時候爲第一放映想到的是@condition註解,貌似該註解是springframework4.x後出現的;之前貌似可以用別的方案實現;

採用註解的方式還是很不錯的,最少直觀易懂;

ok,開始看代碼

首先定義個類實現condition方法,如下:

public class MasterCondition implements Condition {

	@Override
	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		String key=context.getEnvironment().getProperty("readAndwriteKey");
		boolean flag="false".equals(key)? false:true;
		return flag;
	}

}

其中返回false的時候代表的是引用此處的@condition註解是不不加載到容器中來的;true的話就是相反了。

當爲false的時候,在上一篇文章http://blog.csdn.net/liunian02050328/article/details/75090297中定義的路由就沒什麼用了。那麼我們就用@condtion註解一下,如下

       @Conditional(MasterCondition.class)
	@Bean
	public AbstractRoutingDataSource dataSouceProxy() {
		MyAbstractRoutingDataSource proxy = new MyAbstractRoutingDataSource();
		Map<Object, Object> targetDataSource = new HashMap<Object, Object>();
		targetDataSource.put(DataSourceType.slaveDataSource.getDataSource(), slaveDataSource());
		targetDataSource.put(DataSourceType.masterDataSource.getDataSource(), masterDataSource());
		proxy.setTargetDataSources(targetDataSource);
		proxy.setDefaultTargetDataSource(slaveDataSource());
		return proxy;
	}
相同的在上一篇定義的AOP的類上加上相同的註解即可。
此處的路由調度採用了condition註解,啓動的時候沒有加載到容器中來,在引用路由後獲得的datasource時候獲取爲空,肯定會報異常,這時候需要修改方法sqlSessionFactory

具體修改如下:

@Bean
	public SqlSessionFactory sqlSessionFactory() throws Exception {
		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		boolean flag="false".equals(readAndwriteKey);
		
		if (flag) {
			sqlSessionFactoryBean.setDataSource(masterDataSource());
		}else{
			sqlSessionFactoryBean.setDataSource(dataSouceProxy());
		}
		// sqlSessionFactoryBean.setTypeAliasesPackage("com.*.*");
		sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("/config/mybatis-config.xml"));
		PathMatchingResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

		sqlSessionFactoryBean
				.setMapperLocations(resourcePatternResolver.getResources("classpath*:com/xx/xxx/mapper/*Mapper.xml"));
		return sqlSessionFactoryBean.getObject();
	}

上面的這個是不是可以改進下?我是採用的是if  else  判斷,是不是看起來比較low,歡迎高手指正並提出良好的解決方案

當我們根據數據源獲得的sqlsessionfactory之後,ok,下面的就不永講了,相信大家都會使用了。

總結如下:

所謂的讀寫分離,主要做的就是在數據連接底層切換數據源,如何切換呢?一主一從比較簡單,這裏的路由沒怎麼寫路由算法,在一主多從的裏面會涉及到,在後面的章節中會降到。

而設計讀寫分離的開關,無非就是屏蔽路由數據源的方法以及aop。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章