使用AOP 实现多数据源 切换
多数据源的实现,这里就来个实例吧
1、在 spring 的配置文件中数据源信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <?xml version= "1.0" encoding= "UTF-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:context= "http://www.springframework.org/schema/context" xmlns:mvc= "http://www.springframework.org/schema/mvc" xmlns:util= "http://www.springframework.org/schema/util" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:aop= "http://www.springframework.org/schema/aop" xsi:schemaLocation="http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http: //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http: //www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http: //www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.1.xsd http: //www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http: //www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd"> <!-- 加载配置属性文件 --> <context:property-placeholder ignore-unresolvable= "true" location= "classpath:conf.properties" /> <!-- C3P0连接池配置 --> <bean id= "dataSource_zh_CN" class = "com.mchange.v2.c3p0.ComboPooledDataSource" > <property name= "driverClass" value= "${db1.jdbc.driver}" /> <property name= "jdbcUrl" value= "${db1.jdbc.url}" /> <property name= "user" value= "${db1.jdbc.username}" /> <property name= "password" value= "${db1.jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name= "initialPoolSize" value= "${jdbc.pool.init}" /> <property name= "minPoolSize" value= "${jdbc.pool.minIdle}" /> <property name= "maxPoolSize" value= "${jdbc.pool.maxActive}" /> <property name= "maxIdleTime" value= "60000" /> </bean> <!-- C3P0连接池配置 --> <bean id= "dataSource_en_US" class = "com.mchange.v2.c3p0.ComboPooledDataSource" > <property name= "driverClass" value= "${db2.jdbc.driver}" /> <property name= "jdbcUrl" value= "${db2.jdbc.url}" /> <property name= "user" value= "${db2.jdbc.username}" /> <property name= "password" value= "${db2.jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name= "initialPoolSize" value= "${jdbc.pool.init}" /> <property name= "minPoolSize" value= "${jdbc.pool.minIdle}" /> <property name= "maxPoolSize" value= "${jdbc.pool.maxActive}" /> <property name= "maxIdleTime" value= "60000" /> </bean> <bean id= "dataSource" class = "com.bkc.bpmp.core.datasource.DynamicDataSource" > <property name= "targetDataSources" > <map key-type= "java.lang.String" > <entry key= "dataSource_zh_CN" value-ref= "dataSource_zh_CN" /> <entry key= "dataSource_en_US" value-ref= "dataSource_en_US" /> </map> </property> <property name= "defaultTargetDataSource" ref= "dataSource_zh_CN" /> </bean> </beans> |
2、在 Spring 配置文件中配置 AOP 切面信息,当访问 包 com.bkc.bpmp 及下面的子包中的类的方法时
1 2 3 4 5 6 7 8 9 10 11 | <!-- 开启aop注解方式 --> <aop:aspectj-autoproxy proxy-target- class = "false" /> <bean id= "dataSourceInterceptor" class = "com.bkc.bpmp.core.aspectj.DataSourceInterceptor" /> <aop:config> <aop:aspect id= "dataSourceAspect" ref= "dataSourceInterceptor" > <aop:pointcut id= "setDs" expression= "execution(* com.bkc.bpmp..*.*(..))" /> <aop:before method= "setdataSourceCnOrEn" pointcut-ref= "setDs" /> </aop:aspect> </aop:config> |
3、实现 数据源 切面切换的方法,这里假设是根据 locale 来切换数据源的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | package com.bkc.bpmp.core.aspectj; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.i18n.LocaleContextHolder; import com.bkc.bpmp.core.annotation.DbType; import com.bkc.bpmp.core.contants.DbTypeEnum; import com.bkc.bpmp.core.datasource.DatabaseContextHolder; /** * 用于实现 动态数据库切换的AOP 方法类 * * @author ppnie */ public class DataSourceInterceptor { /** * 设置数据源为中文 还是 英文 * @param jp */ public void setdataSourceCnOrEn(JoinPoint jp) { String curLocale = LocaleContextHolder.getLocale().toString(); System.out.println( "==================dataSource_" +curLocale); if (curLocale.equals( "en_US" )) { DatabaseContextHolder.setCustomerType( "dataSource_" +curLocale); } else { DatabaseContextHolder.setCustomerType( "dataSource_zh_CN" ); } logger.info( "=======" + "dataSource_" +curLocale+ "=======" ); } } |
4、自定义动态数据源的切换方法,主要就是 写一个 AbstractRoutingDataSource 的子类啦
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package com.bkc.bpmp.core.datasource; public class DatabaseContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); public static void setCustomerType(String customerType) { contextHolder.set(customerType); } public static String getCustomerType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package com.bkc.bpmp.core.datasource; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DatabaseContextHolder.getCustomerType(); } } |
就这样,达到触发条件的时候,就会去切换数据库啦
作者:panie
出处:http://www.cnblogs.com/panie2015/
如果您希望与我交流互动,欢迎加我微信
本文内容为作者辛苦整理书写,欢迎转载,但请保留文章出处
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?