如何在spring框架中解决多数据源的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在spring框架中解决多数据源的问题相关的知识,希望对你有一定的参考价值。
我首先想到在spring的applicationContext中配置所有的dataSource。这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、mysql等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。但是,我很快发现一个问题:当多用户同时并发访问数据库的时候会出现资源争用的问题。这都是“单例模式”惹的祸。众所周知,我们在使用spring框架的时候,在beanFactory中注册的bean基本上都是采用单例模式,即spring在启动的时候,这些bean就装载到内存中,并且每个bean在整个项目中只存在一个对象。
正因为只存在一个对象,对象的所有属性,更准确说是实例变量,表现得就如同是个静态变量(实际上“静态”与“单例”往往是非常相似的两个东西,我们常常用“静态”来实现“单例”)。拿我们的问题来说,sessionFactory在整个项目中只有一个对象,它的实例变量dataSource也就只有一个,就如同一个静态变量一般。如果不同的用户都不断地去修改dataSource的值,必然会出现多用户争用一个变量的问题,对系统产生隐患。
通过以上的分析,解决多数据源访问问题的关键,就集中在sessionFactory在执行数据持久化的时候,能够通过某段代码去根据客户的需要动态切换数据源,并解决资源争用的问题。 参考技术A 最后修改MultiDataSource的方法getDataSource():java 代码public DataSource getDataSource()
String sp = SpObserver.getSp();
return getDataSource(sp);完整的MultiDataSource代码在附件中。
(五) 动态添加数据源
通过以上方案,我们解决了动态分配数据源的问题,但你可能提出疑问:方案中的数据源都是配置在spring的ApplicationContext中,如果我在程序运行过程中动态添加数据源怎么办?这确实是一个问题,而且在我们的项目中也确实遇到。spring的ApplicationContext是在项目启动的时候加载的。加载以后,我们如何动态地加载新的bean到ApplicationContext中呢?我想到如果用spring自己的方法解决这个问题就好了。所幸的是,在查看spring的源代码后,我找到了这样的代码,编写了DynamicLoadBean类,只要调用loadBean()方法,就可以将某个或某几个配置文件中的bean加载到ApplicationContext中(见附件)。不通过配置文件直接加载对象,在spring的源码中也有,感兴趣的朋友可以自己研究。
(六) 在spring中配置
在完成了所有这些设计以后,我最后再唠叨一句。我们应当在spring中做如下配置:xml 代码<bean id="dynamicLoadBean" class="com.htxx.service.dao.DynamicLoadBean"bean
<bean id="dataSource" class="com.htxx.service.dao.MultiDataSource"
<property name="dataSource"
<ref bean="dataSource1" /propertybean
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
<property name="dataSource"
<ref bean="dataSource" /property
......bean其中dataSource属性实际上更准确地说应当是defaultDataSource,即spring启动时以及在客户没有指定数据源时应当指定的默认数据源。
该方案的优势
首先,这个方案完全是在spring的框架下解决的,数据源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource属性,它甚至都不知道dataSource的改变。唯一不同的是在真正的dataSource与sessionFactory之间增加了一个MultiDataSource。
其次,实现简单,易于维护。这个方案虽然我说了这么多东西,其实都是分析,真正需要我们写的代码就只有MultiDataSource、SpObserver两个类。MultiDataSource类真正要写的只有getDataSource()和getDataSource(sp)两个方法,而SpObserver类更简单了。实现越简单,出错的可能就越小,维护性就越高
开源 Spring Boot 中 Mongodb 多数据源扩展框架
开源 Spring Boot 中 Mongodb 多数据源扩展框架
原创 尹吉欢 猿天地 2019-04-25
在日常工作中,我们通过Spring Data Mongodb来操作Mongodb数据库,在Spring Boot中只需要引入spring-boot-starter-data-mongodb即可。
然后配置连接信息如下:
1. spring.data.mongodb.uri=mongodb://localhost:27017/test
或者
1. pring.data.mongodb.authentication-database= # Authentication database name.
2. spring.data.mongodb.database=test # Database name.
3. spring.data.mongodb.host=localhost # Mongo server host.
4. spring.data.mongodb.password= # Login password of the mongo server.
5. spring.data.mongodb.port=27017 # Mongo server port.
6. spring.data.mongodb.username= # Login user of the mongo server.
spring-boot-starter-data-mongodb提供了两种配置方式,分别是uri和host方式。uri可以配置多个地址,也就是集群的配置方式。host只能连接一个节点。
当在一个项目中需要连接多个数据库的时候,spring-boot-starter-data-mongodb的自动配置无法满足需求,所以我这边封装了一个多数据源的Mongodb spring-boot-starter。
之前关于多数据源的使用写了篇文章:spring-boot-starter-mongodb-pool
由于是第一个版本,有些东西没考虑到,最近更新了下,加了一些内容,升级到Spring Boot 2.0版本。
Github(请为我加颗星): https://github.com/yinjihuan/spring-boot-starter-mongodb-pool
首先还是简单的介绍下如何使用:
配置仓库地址:
1. <repositories>
2. <repository>
3. <id>jitpack.io</id>
4. <url>https://www.jitpack.io</url>
5. </repository>
6. </repositories>
配置最新版本,只支持Spring Boot 2.0
1. <dependency>
2. <groupId>com.github.yinjihuan</groupId>
3. <artifactId>spring-boot-starter-mongodb-pool</artifactId>
4. <version>2.0.2</version>
5. </dependency>
我这边配置方式也是uri和host两种,uri的话是只配置mongo节点信息,跟默认的uri格式不一样,不包含用户信息和连接参数。
URI配置集群
1. spring.data.mongodb.testMongoTemplate.uri=localhost:27017,localhost:27018
2. spring.data.mongodb.testMongoTemplate.username=yinjihuan
3. spring.data.mongodb.testMongoTemplate.password=123456
4. spring.data.mongodb.testMongoTemplate.database=test
5. spring.data.mongodb.testMongoTemplate.authenticationDatabase=admin
HOST方式配置
1. spring.data.mongodb.testMongoTemplate.host=localhost
2. spring.data.mongodb.testMongoTemplate.port=27017
3. spring.data.mongodb.testMongoTemplate.database=test
4. spring.data.mongodb.testMongoTemplate.username=yinjihuan
5. spring.data.mongodb.testMongoTemplate.password=123456
testMongoTemplate就是我们用来操作test数据库的MongoTemplate对象,框架会自动为你创建好,只需要注入使用就可以了。
1. @Autowired
2. @Qualifier("testMongoTemplate")
3. private MongoTemplate testMongoTemplate;
多数据源就配置多个MongoTemplate就行了,比如:
1. spring.data.mongodb.testMongoTemplate.host=localhost
2. spring.data.mongodb.testMongoTemplate.port=27017
3. spring.data.mongodb.testMongoTemplate.database=test
4. spring.data.mongodb.testMongoTemplate.username=yinjihuan
5. spring.data.mongodb.testMongoTemplate.password=123456
6.
7. spring.data.mongodb.test2MongoTemplate.host=localhost
8. spring.data.mongodb.test2MongoTemplate.port=27017
9. spring.data.mongodb.test2MongoTemplate.database=test2
10. spring.data.mongodb.test2MongoTemplate.username=yinjihuan
11. spring.data.mongodb.test2MongoTemplate.password=123456
操作哪个数据库就注入哪个对象:
1. @Autowired
2. @Qualifier("testMongoTemplate")
3. private MongoTemplate testMongoTemplate;
4.
5. @Autowired
6. @Qualifier("test2MongoTemplate")
7. private MongoTemplate test2MongoTemplate;
更新说明
- ? 支持Spring Boot 2.x版本 第一个版本1.0.0只支持Spring Boot的1.x版本
- ? 加上用户认证配置 第一个版本1.0.0中没有加账号密码认证逻辑
- ? 支持集群地址配置 通过uri配置集群信息
想了解框架实现细节的请移步:http://cxytiandi.com/course 或 查看原文
更多技术分享尽在微信群,加群请加我微信 jihuan900。
加入星球特权
1、实战分库分表中间件Sharding-JDBC
2、实战分布式任务调度框架Elastic Job
3、配置中心Apollo实战
4、高并发解决方案之缓存
5、更多课程等你来解锁,20+课程
尹吉欢
我不差钱啊
喜欢作者
以上是关于如何在spring框架中解决多数据源的问题的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 揭秘与实战 服务器篇 - 其他内嵌服务器 发表于 2017-01-03 | Spring框架 | Spri