1. 仿照抽象路由数据源类创建一个抽象mongodb路由模板源的类。因为操作mongodb的是模板。
package com.caiwufei.common.db.mongo;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.util.Assert;
public abstract class AbstractMongoDBRoutingTemplateSource implements InitializingBean{
private Map<Object, Object> targetMongoTemplates;
private Object defaultTargetMongoTemplate;
private Map<Object, MongoTemplate> resolvedMongoTemplates;
private MongoTemplate resolvedDefaultMongoTemplate;
@Override
public void afterPropertiesSet() {
if (this.targetMongoTemplates == null) {
throw new IllegalArgumentException("Property 'targetMongoTemplates' is required");
}
this.resolvedMongoTemplates = new HashMap<Object, MongoTemplate>(this.targetMongoTemplates.size());
for (Map.Entry<Object, Object> entry : this.targetMongoTemplates.entrySet()) {
Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
MongoTemplate mongoTemplate = resolveSpecifiedMongoTemplate(entry.getValue());
this.resolvedMongoTemplates.put(lookupKey, mongoTemplate);
}
if (this.defaultTargetMongoTemplate != null) {
this.resolvedDefaultMongoTemplate = resolveSpecifiedMongoTemplate(this.defaultTargetMongoTemplate);
}
}
protected Object resolveSpecifiedLookupKey(Object lookupKey) {
return lookupKey;
}
protected MongoTemplate resolveSpecifiedMongoTemplate(Object mongoTemplate) throws IllegalArgumentException {
if (mongoTemplate instanceof MongoTemplate) {
return (MongoTemplate) mongoTemplate;
} else {
throw new IllegalArgumentException(
"Illegal data source value - only [org.springframework.data.mongodb.core.MongoTemplate] and String supported: "
+ mongoTemplate);
}
}
protected MongoTemplate determineMongoTemplate() {
Assert.notNull(this.resolvedMongoTemplates, "mongoTemplate router not initialized");
Object lookupKey = determineCurrentLookupKey();
MongoTemplate mongoTemplate = this.resolvedMongoTemplates.get(lookupKey);
if (mongoTemplate == null && (lookupKey == null)) {
mongoTemplate = this.resolvedDefaultMongoTemplate;
}
if (mongoTemplate == null) {
throw new IllegalStateException("Cannot determine target MongoTemplate for lookup key [" + lookupKey + "]");
}
return mongoTemplate;
}
public Object getDefaultTargetMongoTemplate() {
return defaultTargetMongoTemplate;
}
public void setDefaultTargetMongoTemplate(Object defaultTargetMongoTemplate) {
this.defaultTargetMongoTemplate = defaultTargetMongoTemplate;
}
public Map<Object, Object> getTargetMongoTemplates() {
return targetMongoTemplates;
}
public void setTargetMongoTemplates(Map<Object, Object> targetMongoTemplates) {
this.targetMongoTemplates = targetMongoTemplates;
}
protected abstract Object determineCurrentLookupKey();
}
package com.caiwufei.common.db.mongo;
import org.springframework.data.mongodb.core.MongoTemplate;
import com.caiwufei.common.db.DBContextHolder;
public class MongoDynamicTemplateSource extends AbstractMongoDBRoutingTemplateSource{
public MongoTemplate getMongoTemplate(){
return determineMongoTemplate();
}
@Override
protected Object determineCurrentLookupKey() {
return DBContextHolder.Mongo.getTargetMongoTemplate();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xmlns:repository="http://www.springframework.org/schema/data/repository"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/apo/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/data/repository
http://www.springframework.org/schema/data/repository/spring-repository.xsd">
<bean id="mongoMappingContext" class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />
<bean id="mongoTypeMapper" class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">
<constructor-arg name="typeKey">
<null/>
</constructor-arg>
</bean>
<mongo:mapping-converter id="mongoMappingConverter"
base-package="com.caiwufei.entity"
mapping-context-ref="mongoMappingContext"
type-mapper-ref="mongoTypeMapper"/>
<!-- mongo_stg client -->
<mongo:mongo-client id="mongo_stg" host="127.0.0.1" port="23092" credentials="cfsssopr:paic1234@cfsss" >
<mongo:client-options
connect-timeout="5000"
connections-per-host="10"
description="mongo_stg"
heartbeat-connect-timeout="1000"
heartbeat-frequency="100"
heartbeat-socket-timeout="1000"
max-connection-idle-time="1500"
max-connection-life-time="0"
max-wait-time="10000"
min-connections-per-host="5"
min-heartbeat-frequency="10"
read-preference="PRIMARY"
socket-keep-alive="true"
socket-timeout="3000"
ssl="false"
threads-allowed-to-block-for-connection-multiplier="5"
write-concern="NONE" />
</mongo:mongo-client>
<!-- mongo_pro client -->
<mongo:mongo-client id="mongo_pro" host="127.0.0.1" port="24086" credentials="devsup01:safa232wsff@cfsss">
<mongo:client-options
connect-timeout="5000"
connections-per-host="10"
description="mongo_pro"
heartbeat-connect-timeout="1000"
heartbeat-frequency="100"
heartbeat-socket-timeout="1000"
max-connection-idle-time="1500"
max-connection-life-time="0"
max-wait-time="10000"
min-connections-per-host="5"
min-heartbeat-frequency="10"
read-preference="PRIMARY"
socket-keep-alive="true"
socket-timeout="3000"
ssl="false"
threads-allowed-to-block-for-connection-multiplier="5"
write-concern="NONE" />
</mongo:mongo-client>
<!-- mongoDbFactory stg未使用“mongoFactory_stg”,因为框架其他的bean强制使用了“mongoDbFactory”引入 -->
<mongo:db-factory id="mongoDbFactory" dbname="cfsss" mongo-ref="mongo_stg"/>
<mongo:db-factory id="mongoFactory_pro" dbname="cfsss" mongo-ref="mongo_pro"/>
<!-- 两个模板 -->
<mongo:template id="mongoTemplate_stg" db-factory-ref="mongoDbFactory" converter-ref="mongoMappingConverter"/>
<mongo:template id="mongoTemplate_pro" db-factory-ref="mongoFactory_pro" converter-ref="mongoMappingConverter"/>
<!-- 动态数据源模板 -->
<bean id="mongoTemplateSource" class="com.caiwufei.common.db.mongo.MongoDynamicTemplateSource">
<property name="defaultTargetMongoTemplate" ref="mongoTemplate_stg"/>
<property name="targetMongoTemplates">
<map>
<entry key="stg" value-ref="mongoTemplate_stg"></entry>
<entry key="pro" value-ref="mongoTemplate_pro"></entry>
</map>
</property>
</bean>
</beans>
package com.caiwufei.common.db;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import com.caiwufei.common.db.mongo.MongoDynamicTemplateSource;
@Component
public class DBContextHolder{
@Autowired
private MongoDynamicTemplateSource dynamicTemplateSource;
private static DBContextHolder dbContextHolder;
private static final ThreadLocal<String> dbName = new ThreadLocal<String>();
private static final ThreadLocal<String> mongoTemplate = new ThreadLocal<String>();
@PostConstruct
public void init() {
dbContextHolder = this;
dbContextHolder.dynamicTemplateSource = this.dynamicTemplateSource;
}
public void setMongoTemplateSource(MongoDynamicTemplateSource mongoTemplateSource) {
this.dynamicTemplateSource = mongoTemplateSource;
}
public static class DB {
public static void changeTargetDataSource(String dataKey){
dbName.set(dataKey);
}
public static String getTargetDataSource(){
return dbName.get();
}
}
public static class Mongo {
public static void changeTargetMongoTemplate(String mongoTemplateKey){
mongoTemplate.set(mongoTemplateKey);
}
public static String getTargetMongoTemplate(){
return mongoTemplate.get();
}
}
public static MongoTemplate mongoTemplate() {
return dbContextHolder.dynamicTemplateSource.getMongoTemplate();
}
}