您现在的位置是:主页 > news > 构建企业门户网站的方法/广州百度

构建企业门户网站的方法/广州百度

admin2025/6/10 7:19:31news

简介构建企业门户网站的方法,广州百度,做网站设计提成赚钱吗,做装饰工程的在什么网站投标面试时常被问到aop在你们项目中哪些地方用到了,我的回答是事物、日志,再问就回答不上来,最近看了读写分离的视频,发现读写分离也是aop的应用场景之一。spring提供的AbstractRoutingDataSource会在方法afterPropertiesSet中&#x…

构建企业门户网站的方法,广州百度,做网站设计提成赚钱吗,做装饰工程的在什么网站投标面试时常被问到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