irpas技术客

springboot+mongodb多数据源配置_AP0906424_mongodb多数据源配置

未知 1427

目录

1、前言

2、mongodb多数据源配置

2.1?maven依赖

2.2 mongodb配置

2.3 创建mongodb属性类和配置类

3、设置数据源的路由key 以及 查找数据源

3.1 定义数据源枚举

3.2 模板DynamicMongoTemplater

4、切面

4.1 定义切面注解

4.2 切面实现类

5 测试controller


1、前言

今天讲讲mongodb多数据源配置,思路和上一篇springboot+mybatis多数据源配置差不多,jdk版本还是1.8,springboot版本还是1.5.21。

2、mongodb多数据源配置 2.1?maven依赖 <!-- 这是主要的maven依赖,非完整 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 2.2 mongodb配置 ##mongodb数据源, 用户名密码、鉴权这些省略,此处演示不配置 mongodb: databases: mongodb_1: ##这是我自定义的dbname name: mongodb_1 uri: mongodb://192.168.1.15:27017/mongodb_1 mongodb_2: name: mongodb_2 uri: mongodb://192.168.1.15:27017/mongodb_2 2.3 创建mongodb属性类和配置类 import com.alibaba.fastjson.JSONObject; /** * mongodb属性 * @author LongBJ * */ public class MongodbProperties { private String name; private String uri; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } @Override public String toString() { return JSONObject.toJSONString(this); } }

这里的name,uri和配置文件的属性对应,不然后面无法注入。mongodb配置类

/** ** mongodb配置类 **/ @Configuration @ConfigurationProperties(prefix = "mongodb") @PropertySource("classpath:bootstrap.yml") public class MongodbConfig { // databases也要和配置文件属性名对应 private Map<String, MongodbProperties> databases = new HashMap<>(); public Map<String, MongodbProperties> getDatabases() { return databases; } public void setDatabases(Map<String, MongodbProperties> databases) { this.databases = databases; } } 3、设置数据源的路由key 以及 查找数据源 3.1 定义数据源枚举 public enum DataSourceEnum { DS_MONGODB_1("mongodb_1", "mongodb_1数据源"), DS_MONGODB_2("mongodb_2", "mongodb_2数据源"); private String value; private String display; DataSourceEnum(String value, String display) { this.value = value; this.display = display; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getDisplay() { return display; } public void setDisplay(String display) { this.display = display; } }

????????接下来,我们利用ThreadLocal将数据源设置到每个请求的线程上下文当中,代码如下:

port java.net.UnknownHostException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import com.mongodb.MongoClientURI; @Component public class MongodbContextHolder { // 数据源对应的MongoDbFactory Map private static final Map<String, MongoDbFactory> MONGO_CLIENT_DB_FACTORY_MAP = new HashMap<>(); // 当前线程ThreadLocal绑定的数据源工厂 private static final ThreadLocal<MongoDbFactory> MONGO_DB_FACTORY_THREAD_LOCAL = new ThreadLocal<>(); @Autowired private MongodbConfig mongodbConfig; @PostConstruct public void afterPropertiesSet() throws UnknownHostException { Map<String, MongodbProperties> databases = mongodbConfig.getDatabases(); if (!CollectionUtils.isEmpty(databases)) { for(Entry<String, MongodbProperties> entry : databases.entrySet()) { MongodbContextHolder.MONGO_CLIENT_DB_FACTORY_MAP.put(entry.getKey(), new SimpleMongoDbFactory(new MongoClientURI(entry.getValue().getUri()))); } } } @Bean(name = "dynamicMongoTemplate") public DynamicMongoTemplate dynamicMongoTemplate() { Iterator<MongoDbFactory> iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); return new DynamicMongoTemplate(iterator.next()); } @Bean(name = "mongoDbFactory") public MongoDbFactory mongoDbFactory() { Iterator<MongoDbFactory> iterator = MONGO_CLIENT_DB_FACTORY_MAP.values().iterator(); return iterator.next(); } public static void setMongoDbFactory(String name) { MONGO_DB_FACTORY_THREAD_LOCAL.set(MONGO_CLIENT_DB_FACTORY_MAP.get(name)); } public static MongoDbFactory getMongoDbFactory() { return MONGO_DB_FACTORY_THREAD_LOCAL.get(); } public static void removeMongoDbFactory(){ MONGO_DB_FACTORY_THREAD_LOCAL.remove(); } } 3.2 模板DynamicMongoTemplater

? ? ? ? 动态获取mongodb数据源的模板如下:

import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.core.MongoTemplate; import com.mongodb.DB; /** * mongodb数据源动态模板 * @author LongBJ * */ public class DynamicMongoTemplate extends MongoTemplate { public DynamicMongoTemplate(MongoDbFactory mongoDbFactory) { super(mongoDbFactory); } /** * springboot 1.x版本 * 重写getDb */ @Override public DB getDb() { MongoDbFactory mongoDbFactory = MongodbContextHolder.getMongoDbFactory(); return mongoDbFactory.getDb(); } /** * springboot2.x 版本 @Override protected MongoDatabase doGetDatabase() { MongoDbFactory mongoDbFactory = MongodbContextHolder.getMongoDbFactory(); return mongoDbFactory == null ? super.doGetDatabase() : mongoDbFactory.getDb(); }*/ } 4、切面 4.1 定义切面注解 @Documented @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface MongodbDynamicDS { DataSourceEnum value() default DataSourceEnum.DS_KUAIMA_MEDICAL; } 4.2 切面实现类

? ? ? ? 有了切面注解,还需要实现切面拦截,实现非常简单,只需要定义一个类,在类上使用@Aspect和@Component即可实现。

import java.util.Objects; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import com.kingseok.hospital.common.annotation.MongodbDynamicDS; import com.kingseok.hospital.common.configuration.DataSourceEnum; import com.kingseok.hospital.common.mongodb.MongodbContextHolder; /** * mongodb数据源切面 * @author LongBJ * */ @Aspect @Component public class MongodbAspect { private final static Logger _logger = LoggerFactory.getLogger(DynamicDatasourceAspect.class); @Pointcut("@within(com.kingseok.hospital.common.annotation.MongodbDynamicDS)") public void mongodbDSourcePointCut() {} @Pointcut("@annotation(com.kingseok.hospital.common.annotation.MongodbDynamicDS)") public void mongodbDSourcePointCut2() {} @Around("mongodbDSourcePointCut() || mongodbDSourcePointCut2()") public Object getMongodbDynamicDS(ProceedingJoinPoint joinPoint) throws Throwable { DataSourceEnum ds = getDSAnnocation(joinPoint).value(); _logger.info("MongodbAspect : getMongodbDynamicDS -> ds_key={}", ds.getValue()); MongodbContextHolder.setMongoDbFactory(ds.getValue()); try{ return joinPoint.proceed(); }finally { MongodbContextHolder.removeMongoDbFactory(); _logger.info("MongodbAspect : getMongodbDynamicDS -> ThreadLocal已删除ds_key={}", ds.getValue()); } } private MongodbDynamicDS getDSAnnocation(ProceedingJoinPoint joinPoint) { Class<?> targetClazz = joinPoint.getTarget().getClass(); MongodbDynamicDS ds = targetClazz.getAnnotation(MongodbDynamicDS.class); // 先判断类的注解,再判断方法注解 if(Objects.nonNull(ds)) { return ds; } MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); return methodSignature.getMethod().getAnnotation(MongodbDynamicDS.class); } } 5 测试controller @RunWith(SpringRunner.class) @SpringBootTest @MongodbDynamicDS(value = DataSourceEnum.DS_MONGODB_1) public class DatasourceDemoApplicationTests { @Autowired private MongoTemplate dynamicMongoTemplate; @Override public JSONObject getPddImById(String id) { String collectionName = "bizrecord"; // 表名 QueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.and(new BasicDBObject("_id", id)); Query query = new BasicQuery(queryBuilder.get()); JSONObject record = dynamicMongoTemplate.findOne(query, JSONObject.class, collectionName); return record ; } @Test @MongodbDynamicDS(value = DataSourceEnum.DS_MONGODB_1) // 作用于方法上 public JSONObject test() { String collectionName = "bizrecord"; // 表名 QueryBuilder queryBuilder = new QueryBuilder(); queryBuilder.and(new BasicDBObject("_id", id)); Query query = new BasicQuery(queryBuilder.get()); JSONObject record = dynamicMongoTemplate.findOne(query, JSONObject.class, collectionName); return record ; } }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #mongodb多数据源配置 #springboot