AOP实现Spring多数据源操作
来源:互联网 发布:文明6 简体中文 mac版 编辑:程序博客网 时间:2024/05/21 20:28
通过继承Spring的AbstractRoutingDataSource抽象类,对 afterpropertiesset、 determineCurrentLookupKe
1、继承AbstractRoutingDataSource,重写方法
/** * 继承{@link AbstractRoutingDataSource} * @author Cheng.Wei * @ClassName DynamicDataSource * @Description 动态数据源--可根据不同的数据索引连接不同的数据库 * @date 2017-06-13 10:52 */public class DynamicDataSource extends AbstractRoutingDataSource { private DataSource master; // 默认主库 private Map<String, DataSource> synergy; // 其他数据源,允许多个通过 key获取 private Map<Object, Object> dataSources = new HashMap<Object, Object>(); private static final String DEFAULT = DBSource.MASTER.getKey(); private static final ThreadLocal<String> datasourceHolder = new ThreadLocal<String>(); @Override public void afterPropertiesSet() { if (null == master) { throw new IllegalArgumentException("'master' is required"); } dataSources.put(DEFAULT, master); if (null != synergy && synergy.size() > 0) { for (Map.Entry<String, DataSource> entry : synergy.entrySet()) { dataSources.put(entry.getKey(), entry.getValue()); } } this.setDefaultTargetDataSource(master); this.setTargetDataSources(dataSources); super.afterPropertiesSet(); } @Override protected Object determineCurrentLookupKey() { return datasourceHolder.get(); } public static void setDataSource(String dataSource) { datasourceHolder.set(dataSource); } public static void reset() { datasourceHolder.remove(); } public void setMaster(DataSource master) { this.master = master; } public void setSynergy(Map<String, DataSource> synergy) { this.synergy = synergy; }}
2、配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd" default-lazy-init="false"> <context:component-scan base-package="com.dhweicheng"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/> </context:component-scan> <context:property-placeholder location="classpath:config.properties"/> <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"/> <!-- 主库数据数据源 --> <bean id="master-dataSource" parent="druidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${master.connection.url}"/> <property name="username" value="${master.connection.username}"/> <property name="password" value="${master.connection.password}"/> <property name="initialSize" value="${master.druid.initialSize}"/> <property name="maxActive" value="${master.druid.maxActive}"/> <property name="minIdle" value="${master.druid.minIdle}"/> <property name="maxWait" value="${master.druid.maxWait}"/> <property name="poolPreparedStatements" value="${master.druid.poolPreparedStatements}"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="${master.druid.maxPoolPreparedStatementPerConnectionSize}"/> <property name="validationQuery" value="${master.druid.validationQuery}"/> <property name="testOnBorrow" value="${master.druid.testOnBorrow}"/> <property name="testOnReturn" value="${master.druid.testOnReturn}"/> <property name="testWhileIdle" value="${master.druid.testWhileIdle}"/> <property name="timeBetweenEvictionRunsMillis" value="${master.druid.timeBetweenEvictionRunsMillis}"/> <property name="minEvictableIdleTimeMillis" value="${master.druid.minEvictableIdleTimeMillis}"/> <property name="removeAbandoned" value="${master.druid.removeAbandoned}"/> <property name="removeAbandonedTimeout" value="${master.druid.removeAbandonedTimeout}"/> <property name="logAbandoned" value="${master.druid.logAbandoned}"/> <property name="filters" value="${master.druid.filters}"/> </bean> <!-- 从库数据源 --> <bean id="yhz-dataSource" parent="druidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${yhz.connection.url}"/> <property name="username" value="${yhz.connection.username}"/> <property name="password" value="${yhz.connection.password}"/> <property name="initialSize" value="${yhz.druid.initialSize}"/> <property name="maxActive" value="${yhz.druid.maxActive}"/> <property name="minIdle" value="${yhz.druid.minIdle}"/> <property name="maxWait" value="${yhz.druid.maxWait}"/> <property name="poolPreparedStatements" value="${yhz.druid.poolPreparedStatements}"/> <property name="maxPoolPreparedStatementPerConnectionSize" value="${yhz.druid.maxPoolPreparedStatementPerConnectionSize}"/> <property name="validationQuery" value="${yhz.druid.validationQuery}"/> <property name="testOnBorrow" value="${yhz.druid.testOnBorrow}"/> <property name="testOnReturn" value="${yzh.druid.testOnReturn}"/> <property name="testWhileIdle" value="${yhz.druid.testWhileIdle}"/> <property name="timeBetweenEvictionRunsMillis" value="${yhz.druid.timeBetweenEvictionRunsMillis}"/> <property name="minEvictableIdleTimeMillis" value="${yhz.druid.minEvictableIdleTimeMillis}"/> <property name="removeAbandoned" value="${yhz.druid.removeAbandoned}"/> <property name="removeAbandonedTimeout" value="${yhz.druid.removeAbandonedTimeout}"/> <property name="logAbandoned" value="${yhz.druid.logAbandoned}"/> <property name="filters" value="${yhz.druid.filters}"/> </bean> <!--主从库选择--> <bean id="dynamicDataSource" class="com.dhweicheng.core.datasource.DynamicDataSource"> <property name="master" ref="master-dataSource"/> <property name="synergy"> <map key-type="java.lang.String"> <entry key="master" value-ref="master-dataSource"/> <entry key="yhz" value-ref="yhz-dataSource"/> </map> </property> </bean> <!-- 配置数据源 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dynamicDataSource"/> <property name="configLocation" value="classpath:mybatis_cfg.xml"/> <property name="mapperLocations" value="classpath:com/dhweicheng/**/**/mapping/*.xml"/> </bean> <!--mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory basePackage:指定sql映射文件/接口所在的包(自动扫描) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <property name="basePackage" value="com.dhweicheng.web.**.mapper"/> </bean> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource"/> </bean> <tx:annotation-driven transaction-manager="txManager"/></beans>
3、自定义注解
/** * @author Cheng.Wei * @ClassName DataSourceMapping * @Description 基于Java 注解 实现动态数据源动态选择, 默认使用主库 * @date 2017-06-13 10:47 */@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface DataSourceMapping { DBSource value() default DBSource.MASTER;}
4、AOP切换数据源
/** * 有{@link DataSourceMapping}注解的方法,调用时会切换到指定的数据源 * @author Cheng.Wei * @ClassName DataSourceAspect * @Description 基于AOP的多数据远切换 * @date 2017-06-13 13:04 */@Component@Aspectpublic class DataSourceAspect { @Around(value = "@annotation(com.dhweicheng.core.annotation.DataSourceMapping)", argNames = "pjp") public Object doAround(ProceedingJoinPoint pjp) throws Throwable { Object val = null; MethodSignature ms = (MethodSignature) pjp.getSignature(); Method method = ms.getMethod(); DataSourceMapping annotation = method.getAnnotation(DataSourceMapping.class); boolean changeDataSource = false; try { if (null != annotation) { changeDataSource = true; DynamicDataSource.setDataSource(annotation.value().getKey()); } val = pjp.proceed(); } catch (Throwable e) { throw e; } finally { if (changeDataSource) { DynamicDataSource.reset(); } } return val; }}
@Override@DataSourceMapping(DBSource.YHZ_DATASOURCE)public Role selectByPrimaryKey(Integer id) { return roleMapper.selectByPrimaryKey(id);}注意配置:
<aop:aspectj-autoproxy proxy-target-class="true"/>
阅读全文
1 0
- AOP实现Spring多数据源操作
- 初尝Spring AOP --实现多数据源切换
- Spring AOP 动态多数据源
- spring AOP多数据源读写分离
- spring实现多数据源
- Spring多数据源实现
- spring多数据源配置+aop注解方式属性注入
- 使用Aop和AbstractRoutingDataSource实现多数据源的配置
- springboot + mybatis + 多数据源 (AOP实现)
- SSM框架多数据源AOP注解方式实现
- hibernate4+spring实现多数据源切换
- Spring实现多数据源动态切换
- Spring中实现多数据源事务管理
- Spring+MyBatis多数据源配置实现
- Spring 的AbstractRoutingDataSource实现多数据源
- Spring+MyBatis多数据源配置实现
- Spring+MyBatis多数据源配置实现
- Spring mvc实现动态多数据源
- easyui表单多Bean加载与提交
- Leetcode 104 Maximum Depth of Binary Tree
- 主机上连接到 vmware虚拟机的方式
- 架构师之路16年精选50篇
- 使用Jquery的getJSON跨域请求蘑菇街图片资源实现瀑布流
- AOP实现Spring多数据源操作
- 我的github&&Git学习资源
- 82-83_游戏项目_使用继承封装MyFrame作为以后窗口类共同父类
- 基础技术篇 7 —— NB-IoT技术(二)
- Android-APP之桌面宠物
- [leetCode刷题笔记]113. Path Sum II
- tomcat在add项目的时候,project facet java version 6.0 is not supported
- R中lines()和abline()函数
- 使用ViewFlipper实现屏幕切换动画效果