spring读写分离
Posted smile_elims
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring读写分离相关的知识,希望对你有一定的参考价值。
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class ChooseDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return HandleDataSource.getDataSource(); } }
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * RUNTIME 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 * * @author yangGuang * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DataSource { String value(); }
import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.reflect.MethodSignature; public class DataSourceAspect { /** * 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源 * * @param point * @throws Exception */ public void intercept(JoinPoint point) throws Exception { Class<?> target = point.getTarget().getClass(); MethodSignature signature = (MethodSignature) point.getSignature(); // 默认使用目标类型的注解,如果没有则使用其实现接口的注解 for (Class<?> clazz : target.getInterfaces()) { resolveDataSource(clazz, signature.getMethod()); } resolveDataSource(target, signature.getMethod()); } /** * 提取目标对象方法注解和类型注解中的数据源标识 * * @param clazz * @param method */ private void resolveDataSource(Class<?> clazz, Method method) { try { Class<?>[] types = method.getParameterTypes(); // 默认使用类型注解 if (clazz.isAnnotationPresent(DataSource.class)) { DataSource source = clazz.getAnnotation(DataSource.class); HandleDataSource.putDataSource(source.value()); } // 方法注解可以覆盖类型注解 Method m = clazz.getMethod(method.getName(), types); if (m != null && m.isAnnotationPresent(DataSource.class)) { DataSource source = m.getAnnotation(DataSource.class); HandleDataSource.putDataSource(source.value()); } } catch (Exception e) { // System.out.println(clazz + ":" + e.getMessage()); } } }
public class HandleDataSource { public static final ThreadLocal<String> holder = new ThreadLocal<String>(); public static void putDataSource(String datasource) { holder.set(datasource); } public static String getDataSource() { return holder.get(); } public static void clearDataSource() { holder.remove(); } }
spring配置文件
<bean id="dataSource" class="hometree.ecs.business.db.dao.util.ChooseDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <!-- write --> <entry key="write" value-ref="writeDataSource"/> <!-- read --> <entry key="read" value-ref="readDataSource"/> <!-- 读写 --> <entry key="wr" value-ref="dataSourceAdmin"/> </map> </property> <!-- 默认 --> <property name="defaultTargetDataSource" ref="dataSourceAdmin"/> </bean> <!-- 激活自动代理功能 --> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 配置数据库注解aop --> <bean id="dataSourceAspect" class="aa.dd.cc.DataSourceAspect" /> <aop:config> <aop:aspect id="c" ref="dataSourceAspect"> <!--扫描下边的所有方法都要过before --> <aop:pointcut id="tx" expression="execution(* aa.dd.cc.*.*(..))"/> <aop:before pointcut-ref="tx" method="intercept"/> <!-- intercept是执行的方法 --> </aop:aspect> </aop:config> <!-- 配置数据库注解aop -->
在方法调用上:
@DataSource("read")//read与
<entry key="read" value-ref="readDataSource"/> 对应
public void add(){
}
以上是关于spring读写分离的主要内容,如果未能解决你的问题,请参考以下文章