Spring aop读写分离
2016-06-20 16:00
411 查看
一、采用读写分离技术的目标
随着网站的业务不断扩展,数据不断增加,用户越来越多,数据库的压力也就越来越大,采用传统的方式,比如:数据库或者SQL的优化基本已达不到要求,这个时候可以采用读写分离的策略来改变现状。采用读写分离技术能够有效减轻Master库的压力,又可以把用户查询数据的请求分发到不同的Slave库,从而保证系统的健壮性。二、常用的两种方式
1、定义两个数据库链接,一个是masterDataSource,另个是slaveDataSource,更新数据时读取masterDataSource,查询是读取slaveDataSource。2、动态数据源切换,在程序运行时,把数据源动态织如入程序中,从而选择主库还是从库。主要技术采用annotation,Spring AOP,反射,接下来详细介绍该种方法。
三、动态数据源切换实现读写分离
1,定义DataSource注解
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)
public @interface DataSource {
String value();
}
2,继承抽象类AbstractRoutingDataSource来实现DynamicDataSource方法
public class DynamicDataSource extends AbstractRoutingDataSource{public static final Logger logger = Logger.getLogger(DynamicDataSource.class.toString());
@Override
protected Object determineCurrentLookupKey() {
return DynamicDataSourceHolder.getDataSource();
}
}
3,定义DynamicDataSourceHolder方法
public class DynamicDataSourceHolder {private static final ThreadLocal<String> holder = new ThreadLocal<String>();
public static void setDataSource(String name) {
holder.set(name);
}
public static String getDataSource() {
return holder.get();
}
}
4,定义DataSourceAspect类,在程序运行时动态切换数据源
public class DataSourceAspect {public void before(JoinPoint point){
Object target = point.getTarget();
String method = point.getSignature().getName();
Class<?>[] classz = target.getClass().getInterfaces();
Class<?>[] parameterTypes = ((MethodSignature)point.getSignature()).getParameterTypes();
try{
Method m = classz[0].getMethod(method, parameterTypes);
if(m != null && m.isAnnotationPresent(DataSource.class)){
DataSource date = m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(date.value());
}
else {
// 默认master
DynamicDataSourceHolder.setDataSource("master");
}
}catch(Exception e){
}
}
}
5,applicationContext-dataSource.xml配置
分别定义主从数据源后,再添加选择数据源的bean<bean id="dataSource" class="****">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="master" value-ref="masterDataSource"/>
<entry key="slave" value-ref="slaveDataSource"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="masterDataSource"/>
</bean>
增加aop配置
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> <bean id="manyDataSourceAspect" class="****.DataSourceAspect" />
<aop:config>
<aop:aspect id="c" ref="manyDataSourceAspect">
<aop:before method="before" pointcut="execution(* *****.data.dao.*.*(..))"></aop:before>
</aop:aspect>
</aop:config>
6,DAO层定义方法的数据源
@DataSource(value="slave")public ImUser findById(int id);
相关文章推荐
- JAVA 对象大小
- retrofit2+rxjava+mockserver使用和理解
- Java基础学习总结——Java对象的序列化和反序列化
- java对象和json对象互相转换
- java Exception in thread "main" java.lang.NoClassDefFoundError: (wrong name: ) 解决方案
- java开发编译器:自底向上语法解析的基本原理
- Java Annotation
- java.lang.IllegalStateException: No activity
- BOS项目练习(activiti,历史数据操作,流程变量,任务组,监听器,网关,spring整合)
- java 值传递和对象传递
- (转)java反编译i++和++i问题
- eclipse(快捷键)积累中............
- Cookie学习和个人浅见
- Java InputStream读取数据问题
- 谈谈我对类加载器的理解
- NumberOf1 Java解法
- java中的函数式编程(一)
- java7的新特性
- Java实现AES加密解密
- 《java并发编程实战》第10章:避免活跃性危险