原理使用spring aop进行织入
1.创建3个类
3 import java.lang.annotation.*; 4 /** 5 * 多数据源 6 * @author mengxu 7 * @version 2022-12-1 8 */ 9 @Target({ElementType.TYPE, ElementType.METHOD}) 10 @Retention(RetentionPolicy.RUNTIME) 11 @Documented 12 public @interface DataSourceAnnotation { 13 14 String value(); 15 16 String primary = "primary"; 17 18 String secend= "secend"; 19 20 }
2 3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 /** 5 * 多数据源 6 * @author mengxu 7 * @version 2022-12-1 8 */ 9 public class DynamicDataSource extends AbstractRoutingDataSource { 10 11 /** 12 * 数据源标识,保存在线程变量中,避免多线程操作数据源时互相干扰 13 */ 14 private static final ThreadLocal<String> key = new ThreadLocal<String>(); 15 16 @Override 17 protected Object determineCurrentLookupKey() { 18 return key.get(); 19 } 20 21 /** 22 * 设置数据源 23 * 24 * @param dataSource 数据源名称 25 */ 26 public static void setDataSource(String dataSource) { 27 key.set(dataSource); 28 } 29 30 /** 31 * 获取数据源 32 * 33 * @return 34 */ 35 public static String getDatasource() { 36 return key.get(); 37 } 38 39 /** 40 * 清除数据源 41 */ 42 public static void clearDataSource() { 43 key.remove(); 44 } 45 46 }
2 3 import org.slf4j.Logger; 4 import org.slf4j.LoggerFactory; 5 import org.springframework.aop.AfterReturningAdvice; 6 import org.springframework.aop.MethodBeforeAdvice; 7 import org.springframework.stereotype.Component; 8 9 import java.lang.reflect.Method; 10 /** 11 * 多数据源 12 * @author mengxu 13 * @version 2022-12-1 14 */ 15 @Component 16 public class DynamicDataSourceAspect implements MethodBeforeAdvice, AfterReturningAdvice { 17 18 Logger log = LoggerFactory.getLogger(getClass()); 19 20 @Override 21 public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { 22 //这里做一个判断,有使用DataSourceAnnotation注解时才关闭数据源,有一个主要的数据源,就没有必要每次都去关闭 23 if (method.isAnnotationPresent(DataSourceAnnotation.class)) { 24 DynamicDataSource.clearDataSource(); 25 log.debug("数据源已关闭"); 26 } 27 } 28 29 /** 30 * 拦截目标方法,获取由@DataSourceAnnotation指定的数据源标识,设置到线程存储中以便切换数据源 31 */ 32 @Override 33 public void before(Method method, Object[] objects, Object o) throws Throwable { 34 if (method.isAnnotationPresent(DataSourceAnnotation.class)) { 35 DataSourceAnnotation dataSourceAnnotation = method.getAnnotation(DataSourceAnnotation.class); 36 DynamicDataSource.setDataSource(dataSourceAnnotation.value()); 37 log.debug("数据源切换为:" + DynamicDataSource.getDatasource()); 38 } 39 } 40 }
2.在spring配置文件中配置命名空间
1:
xmlns:aop="http://www.springframework.org/schema/aop"
2:
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
更改spring中的数据源 并配置aop的切面
1 <!-- 动态数据源配置 --> 2 <bean id="dataSource" class="com.jeeplus.modules.dynamic.DynamicDataSource"> 3 <property name="targetDataSources"> 4 <map key-type="java.lang.String"> 5 <entry key="primary" value-ref="dataSourcePrimary"></entry> 6 <entry key="secend" value-ref="dataSourceSecend"></entry> 7 </map> 8 </property> 9 <!-- 配置默认数据源 --> 10 <property name="defaultTargetDataSource" ref="dataSourcePrimary"></property> 11 </bean>
第一个数据源自行配置,跟第二个一样 12 <!--多数据源 第二个 数据源 --> 13 <bean id="dataSourceSecend" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 14 <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass --> 15 <property name="driverClassName" value="${jdbc.driver}" /> 16 <!-- 基本属性 url、user、password --> 17 <property name="url" value="${jdbc.urlsecend}" /> 18 <property name="username" value="${jdbc.usernamesecend}" /> 19 <property name="password" value="${jdbc.passwordsecend}" /> 20 <!-- 配置初始化大小、最小、最大 --> 21 <property name="initialSize" value="${jdbc.pool.init}" /> 22 <property name="minIdle" value="${jdbc.pool.minIdle}" /> 23 <property name="maxActive" value="${jdbc.pool.maxActive}" /> 24 <!-- 配置获取连接等待超时的时间 --> 25 <property name="maxWait" value="60000" /> 26 <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> 27 <property name="timeBetweenEvictionRunsMillis" value="60000" /> 28 <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> 29 <property name="minEvictableIdleTimeMillis" value="300000" /> 30 <property name="validationQuery" value="${jdbc.testSql}" /> 31 <property name="testWhileIdle" value="true" /> 32 <property name="testOnBorrow" value="false" /> 33 <property name="testOnReturn" value="false" /> 34 <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用) 35 <property name="poolPreparedStatements" value="true" /> 36 <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> --> 37 <!-- 配置监控统计拦截的filters --> 38 <property name="filters" value="stat" /> 39 </bean> 40 <bean id="dynamicDataSourceAspect" class="com.jeeplus.modules.dynamic.DynamicDataSourceAspect"> 41 </bean> 42 <!--设置切面 com.test.service.*.impl.*()--> 43 <aop:config proxy-target-class="true"> 44 <aop:pointcut id="myPointcut" expression="execution(* com.xxx.modules.order.*.service.*.*(..))"/> 45 <aop:advisor advice-ref="dynamicDataSourceAspect" pointcut-ref="myPointcut" order="1"/> 46 <!--把事务控制在Service层--> 47 <!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" order="2"/>--> 48 </aop:config>
然后在方法上添加注解
@DataSourceAnnotation(DataSourceAnnotation.secend)
public Page<XXX> findPage(Page<xxx> page, XXX xxx) {
return super.findPage(page, xxx);
}
搞定啦!
标签:集成,DataSourceAnnotation,数据源,aop,ssm,import,org,public From: https://www.cnblogs.com/aniymx/p/16955457.html