您现在的位置是:主页 > news > 构建企业门户网站的方法/广州百度
构建企业门户网站的方法/广州百度
admin2025/6/10 7:19:31【news】
简介构建企业门户网站的方法,广州百度,做网站设计提成赚钱吗,做装饰工程的在什么网站投标面试时常被问到aop在你们项目中哪些地方用到了,我的回答是事物、日志,再问就回答不上来,最近看了读写分离的视频,发现读写分离也是aop的应用场景之一。spring提供的AbstractRoutingDataSource会在方法afterPropertiesSet中&#x…
面试时常被问到aop在你们项目中哪些地方用到了,我的回答是事物、日志,再问就回答不上来,最近看了读写分离的视频,发现读写分离也是aop的应用场景之一。
spring提供的AbstractRoutingDataSource会在方法afterPropertiesSet中,将数据源从targetDataSources属性中取出来,put进Map resolvedDataSources
@Override
public void afterPropertiesSet() {
if (this.targetDataSources == null) {
throw new IllegalArgumentException("Property 'targetDataSources' is required");
}
this.resolvedDataSources = new HashMap(this.targetDataSources.size());
for (Map.Entry entry : this.targetDataSources.entrySet()) {
Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
this.resolvedDataSources.put(lookupKey, dataSource);
}
if (this.defaultTargetDataSource != null) {
this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
}
}
调用service方法的时候,通过lookupKey 在resolvedDataSources中get到对应的dataSource
/**
* Retrieve the current target DataSource. Determines the
* {@link #determineCurrentLookupKey() current lookup key}, performs
* a lookup in the {@link #setTargetDataSources targetDataSources} map,
* falls back to the specified
* {@link #setDefaultTargetDataSource default target DataSource} if necessary.
* @see #determineCurrentLookupKey()
*/
protected DataSource determineTargetDataSource() {
Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");
Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
dataSource = this.resolvedDefaultDataSource;
}
if (dataSource == null) {
throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
}
return dataSource;
}
添加一个aop切面,在service之前判断如果方法名以"query", "find", "get"开头,就走从库,否则走写库
/**
* 定义数据源的AOP切面,通过该Service的方法名判断是应该走读库还是写库
*
* @author zhijun
*
*/
public class DataSourceAspect {
/**
* 在进入Service方法之前执行
*
* @param point 切面对象
*/
public void before(JoinPoint point) {
// 获取到当前执行的方法名
String methodName = point.getSignature().getName();
if (isSlave(methodName)) {
// 标记为读库
DynamicDataSourceHolder.markSlave();
} else {
// 标记为写库
DynamicDataSourceHolder.markMaster();
}
}
/**
* 判断是否为读库
*
* @param methodName
* @return
*/
private Boolean isSlave(String methodName) {
// 方法名以query、find、get开头的方法名走从库
return StringUtils.startsWithAny(methodName, "query", "find", "get");
}
}
/**
*
* 使用ThreadLocal技术来记录当前线程中的数据源的key
*
* @author zhijun
*
*/
public class DynamicDataSourceHolder {
//写库对应的数据源key
private static final String MASTER = "master";
//读库对应的数据源key
private static final String SLAVE = "slave";
//使用ThreadLocal记录当前线程的数据源key
private static final ThreadLocal holder = new ThreadLocal();
/**
* 设置数据源key
* @param key
*/
public static void putDataSourceKey(String key) {
holder.set(key);
}
/**
* 获取数据源key
* @return
*/
public static String getDataSourceKey() {
return holder.get();
}
/**
* 标记写库
*/
public static void markMaster(){
putDataSourceKey(MASTER);
}
/**
* 标记读库
*/
public static void markSlave(){
putDataSourceKey(SLAVE);
}
}
定义动态数据源,继承Spring提供的AbstractRoutingDataSource类,实现determineCurrentLookupKey方法,根据lookupKey从resolvedDataSources中get到对应的数据源
/**
* 定义动态数据源,实现通过集成Spring提供的AbstractRoutingDataSource,只需要实现determineCurrentLookupKey方法即可
*
* 由于DynamicDataSource是单例的,线程不安全的,所以采用ThreadLocal保证线程安全,由DynamicDataSourceHolder完成。
*
* @author zhijun
*
*/
public class DynamicDataSource extends AbstractRoutingDataSource{
@Override
protected Object determineCurrentLookupKey() {
// 使用DynamicDataSourceHolder保证线程安全,并且得到当前线程中的数据源key
return DynamicDataSourceHolder.getDataSourceKey();
}
}
配置DynamicDataSource类,项目启动时自动为AbstractRoutingDataSource类注入读、写数据源属性到targetDataSources属性,spring的AbstractRoutingDataSource类再从targetDataSources中put进resolvedDataSources
destroy-method="close">
destroy-method="close">
配置读(从)、写(主)数据源的数据库连接信息,
jdbc.master.driver=com.mysql.jdbc.Driver
jdbc.master.url=jdbc:mysql://127.0.0.1:3381/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.master.username=root
jdbc.master.password=root
jdbc.slave01.driver=com.mysql.jdbc.Driver
jdbc.slave01.url=jdbc:mysql://127.0.0.1:3380/taotao?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
jdbc.slave01.username=root
jdbc.slave01.password=root
标签:jdbc,resolvedDataSources,targetDataSources,数据源,读写,分离,key,mysql,public
来源: https://blog.csdn.net/noob9527/article/details/89040268