Spring AOP动态多数据源实例详解
Spring AOP动态多数据源实例详解
项目中使用读写分离时,会遇到数据源多的问题。多数据源最头疼的不是如何配置多个数据源,而是如何灵活动态地切换数据源。例如,在spring和Mybatis框架的一个项目中,我们经常在spring配置中配置一个数据源连接到数据库,然后将其绑定到sessionFactory,然后在dao层代码中指定sessionFactory来操作数据库。
如上图所示,每个区块都被指定为捆绑。如果有多个数据源,只能是下图所示的方式。
可以看到,Dao层代码中有两个SessionFactory被写死了,所以如果以后多了一个数据源,就需要更改代码添加一个session factory,这显然不符合开放封闭原则。
那么正确的方法应该是:
具体代码和配置如下:
1、应用上下文管理器xml
?可扩展标记语言版本='1.0 '编码='utf-8 '?beans xmlns=' http://www。弹簧框架。org/schema/beans ' xmlns : xsi=' http://www .w3。org/2001/XMLSchema-instance ' xmlns : AOP=' http://www .弹簧框架。org/schema/AOP ' xmlns : context=' http://www .弹簧框架。org/schema/context ' xmlns : tx=' 33http://www-使用注释-上下文:注释-配置/上下文:组件-扫描基本包=' com。卡尔。o2o。* *。mgr/context :组件-扫描!-master-bean id=' master ' class=' com。麦克汉格。v2。C3 p 0。“comboboleddatasource”属性名称=' driverClass '值='${driverClassName_master}'/属性名称=“用户”值='${username_master}'/属性名称='密码'值='${password_master}'/属性名称='jdbcUrl '值='${url_master}?unicode=真字符编码=UTF-8allowmultiquery=真/属性名='maxPoolSize '值='150'/属性名='minPoolSize '值='10'/属性名='initialPoolSize '值='20'/属性名='maxIdleTime '值='3600'/属性名='acquireIncrement '值='10'/属性名='idleConnectionTestPeriod '值=' 1800 '/bean!-slave-bean id=' slave ' class=' com。MC变化。v2。C3 P0。“comboboleddatasource”属性名称=' driverClass '值='${driverClassName_slave}'/属性名称=“用户”值='${username_slave}'/属性名称='密码'值='${password_slave}'/属性名称='jdbcUrl '值='${url_slave}?unicode=真字符编码=UTF-8 /属性名='maxPoolSize '值='150'/属性名='minPoolSize '值='10'/属性名='initialPoolSize '值='20'/属性名='maxIdleTime '值='3600'/属性名='acquireIncrement '值='10'/属性名='idleConnectionTestPeriod '值=' 1800 '/bean!春天动态数据源-bean id='动态数据源' class=' com。卡尔。dbutil。'动态数据源'属性名=“目标数据源”映射键-类型='java.lang.String '条目键='奴隶'值-ref=' slave '/map/属性名=' defaulttargetdata source ' ref=' master '/bean!-my batis mapper config-bean id=' sqlSessionFactory ' class=' org。我的蜡染。春天。sqlsessionfactrybean '属性名='数据源' ref=' dynamicdata source '/属性名=' config location '值=' class path : o2o _ my batis _ config。XML '/属性名=“映射器位置”列表值类路径3360 qlmap/* .XML/value值类路径* :/com/Carl/o2o/* */* .XML/value/list/property/bean id=' SQL session ' class=' org。我的蜡染。春天。sqlsessiontemplate '构造函数-arg索引=' 0 ' ref=' sqlSessionFactory '/构造函数-arg/bean class=' org。我的蜡染。春天。映射器。mapper scannerconfigurer '属性名称='基本包'值=' com。卡尔。o2o。* * .经理。刀//豆!-多数据源AOP-bean id=' data source SPECT ' class=' com。卡尔。dbutil。datasourcespect '/AOP :配置AOP :顾问切入点=' execution(* com。卡尔。o2o。经理*).*(.))'建议-ref=' data source SPECT '/AOP :配置!-事务比恩名称='事务管理器' class=' org。弹簧框架。JDBC。数据源。dataSource etransactionmanager '属性名称='数据源' ref=' dynamicDataSource '/属性/bean/bean 2、动态数据源
DynamicDataSource使用春天中的代码结合面向切面编程实现多数据源切换。
公共类DynamicDataSource扩展了abstractroutingdata source { public dynamic data source(){ }受保护对象determinecurientlookpkey(){ return dbcontextholder。getdbtype();} public Logger getParentLogger(){ 0返回null}}3、DBContextHolder
DynamicDataSource的辅助类,用于实际的切换多数据源。
公共类DBContextHolder { private static ThreadLocalString contextHolder=new ThreadLocal();公共静态字符串MASTER=' master '公共静态字符串SLAVE=' slavepublic DBContextHolder(){ } public static String getDbType(){ String db=(String)contextholder。get();if(db==null){ db=MASTER;}返回数据库;} public static void setDbType(String str){ context holder。set(str);} public static void setMaSter(){ context holder。set(MASTER);} public static void setSlave(){ context holder。set(SLAVE);} public static void clearDBType(){ context holder。移除();}}4、数据源预期
多数据源面向切面编程切面编程实现。
公共类数据源预期实现MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice {私有静态最终日志记录器日志=logmanager。getlogger(datasourcespect。类);公共数据源SPECT(){ }之前的公共void(方法m,对象[]参数,对象目标)引发Throwable { try { if(m!=null){ if()(m . GetName().startsWith('list') || m.getName().开始开关(' select ')| | m . getname().startsWith('get') || m.getName().以(' count ')开头!m.getName().包含(' FromMaSter '){ DBContextholder。SetDbType('从');} else { dbcontextholder。setdbtype(' master ');} } } catch(Exception var5){ log。错误(“”数据源方面错误,var5);} }公共空的在(连接点){ log。信息('在method.current id {}后清除类型),新对象[]{ long。(线程的值。currentthread().getId())});dbcontextholder。cleardbtype();}返回后公开作废(对象返回值,方法方法,对象[]参数,对象目标)抛出抛出后的可抛出{ }公共void(方法方法,对象[]参数,对象目标,例外(ex)抛出可抛出{ log.info('当前数据库类型{ }出现异常时,新建对象[]{ dbcontextholder。getdbtype()});dbcontextholder。setdbtype(' master ');}}以上就是弹簧面向切面编程动态多数据源的实例详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
版权声明:Spring AOP动态多数据源实例详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。