详解使用spring aop实现业务层mysql 读写分离

网友投稿 207 2023-06-20


详解使用spring aop实现业务层mysql 读写分离

spring aop , mysql 主从配置 实现读写分离,接下来把自己的配置过程,以及遇到的问题记录下来,方便下次操作,也希望给一些朋友带来帮助。

1.使用spring aop 拦截机制现数据源的动态选取。

import java.lang.annotation.ElementType;

import java.lang.annotation.Target;

import java.lang.annotation.Retention;

import java.lang.annotation.Rehttp://tentionPolicy;

/**

* RUNTIME

* 编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。

* @author yangGuang

*

*/

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.METHOD)

public @interface DataSource {

String value();

}

3.利用Spring的AbstractRoutingDataSource解决多数据源的问题

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class ChooseDataSource extends AbstractRoutingDataSource {

@Override

protected Object determineCurrentLookupKey() {

return HandleDataSource.getDataSource();

}

}

4.利用ThreadLocal解决线程安全问题

public class HandleDataSource {

public static final ThreadLocal holder = new ThreadLocal();

public static void putDataSource(String datasource) {

holder.set(datasource);

}

public static String getDataSource() {

return holder.get();

}

}

5.定义一个数据源切面类,通过aop访问,在spring配置文件中配置了,所以没有使用aop注解。

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;

//@Aspect

//@Component

public class DataSourceAspect {

//@Pointcut("execution(* com.apc.cms.service.*.*(..))")

public void pointCut(){};

// @Before(value = "pointCut()")

public void before(JoinPoint point)

{

Object target = point.getTarget();

System.out.println(target.toString());

String method = point.getSignature().getName();

System.out.println(method);

Class>[] classz = target.getClass().getInterfaces();

Class>[] parameterTypes = ((MethodSignature) point.getSignature())

.getMethod().getParameterTypes();

try {

Method m = classz[0].getMethod(method, parameterTypes);

System.out.println(m.getName());

if (m != null && m.isAnnotationPresent(DataSource.class)) {

DataSource data = m.getAnnotation(DataSource.class);

HandleDataSource.putDataSource(data.value());

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

6.配置applicationContext.xml

expression="org.springframework.stereotype.Component" />

7.使用注解,动态选择数据源,分别走读库和写库。

@DataSource("write")

public void update(User user) {

userMapper.update(user);

}

@DataSource("read")

public Document getDocById(long id) {

return documentMapper.getById(id);

}

测试写操作:可以通过应用修改数据,修改主库数据,发现从库的数据被同步更新了,所以定义的write操作都是走的写库

测试读操作:  后台修改从库数据,查看主库的数据没有被修改,在应用页面中刷新,发现读的是从库的数据,说明读写分离ok。

遇到的问题总结:

问题1:项目是maven工程,用到了Spring aop机制,除了spring的核心jar包以为,还需要用到的jar包有aspectj.jar,aspectjweaver.jar,aopalliance.jar查看项目中的pom,发现缺少依赖包,由于本地仓库没有这些jar,查找可以提供下载jar包的maven中央库库,配置到maven中,自动更新:

nexus

nexus

http://repository.sonatype.org/content/groups/public/

default

配置项目依赖的jar,主要是缺少这两个。

aspectj

aspectjrt

1.5.4

aspectj

aspectjweaver

1.5.4

lt;/dependency>

expression="org.springframework.stereotype.Component" />

7.使用注解,动态选择数据源,分别走读库和写库。

@DataSource("write")

public void update(User user) {

userMapper.update(user);

}

@DataSource("read")

public Document getDocById(long id) {

return documentMapper.getById(id);

}

测试写操作:可以通过应用修改数据,修改主库数据,发现从库的数据被同步更新了,所以定义的write操作都是走的写库

测试读操作:  后台修改从库数据,查看主库的数据没有被修改,在应用页面中刷新,发现读的是从库的数据,说明读写分离ok。

遇到的问题总结:

问题1:项目是maven工程,用到了Spring aop机制,除了spring的核心jar包以为,还需要用到的jar包有aspectj.jar,aspectjweaver.jar,aopalliance.jar查看项目中的pom,发现缺少依赖包,由于本地仓库没有这些jar,查找可以提供下载jar包的maven中央库库,配置到maven中,自动更新:

nexus

nexus

http://repository.sonatype.org/content/groups/public/

default

配置项目依赖的jar,主要是缺少这两个。

aspectj

aspectjrt

1.5.4

aspectj

aspectjweaver

1.5.4

lt;/dependency>


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序 Template详解及简单实例
下一篇:echarts3 使用总结(绘制各种图表,地图)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~