Spring实现多数据源配置的思想和使用方式

        实际的项目中,经常会用到不同的数据库以满足项目的实际需求。为了解决在不同的类中注入相同类型的数据库连接对象JdbcTemplate,而在真正使用的时候根据会自己的要求,分别使用不同的数据库连接的问题。就要使用到Spring管理多数据源的一种思想。

   --> 比如:项目中将大量插入操作和频繁的查询操作分成两个数据库进行,伪代码如下(直接dao层):
               
我们需要使用同一个JdbcTemplate对象,但是在select的时候我想使用数据库1,而插入的时候我想选择数据库2,这个时候我们就需要使用Spring帮助我们管理不同的数据源。 JdbcTemplate在配置的时候需要指定具体的DataSource,因为要根据这个数据源进行连接的获取,因此单个的数据源显然不能符合我们的要求。
                              
但是, 一切还是从源代码出发,看一下jdbcTempalte的execute的源码,观察是怎么样获取到数据源和连接。

关于DataSource,如上在Spring实际注入对象的过程中,已经将DataSource设置进去,这里暂时不讨论该DataSource使用的具体类型。由JdbcTempalte的继承关系中看出,setDataSource()方法是从JdbcAccessor中继承。

                 

关于Connection,我们从jdbcTemplate的实际执行的execute方法为入口,观察代码的走向,


从源码可以看出,一开始就需要根据指定的数据源获取数据库的连接,继续往下走,会发现实际获取连接的位置。

看到这里,你会发现,JdbcTempalte获取的连接就是根据我们给定的DataSource进行方法的调用,没有什么复杂的逻辑,那么配置多数据源无疑就要从getConnetion为入口。打开Ctrl_T 你可以看到许多不同的数据库连接的实现。因为我们需要按照我们自己的逻辑去实现获取不同的数据源,所以我们需要扩展这个方法按照我们的业务进行操作。所以你完全可以自己继承DataSource并封装一个Map作为数据源的保存,然后在覆写其中获取连接的方法满足自己的业务要求即可。

当然,为了避免反复造轮子,我们使用spring已经提供的AbstractRoutingDataSource抽象可扩展的类实现我们的逻辑。


-->解决思路:使用spring提供的多数据源思想结合AOP进行动态配置,ThreadLocal进行动态数据存储。

①:继承AbstractRoutingDataSource,实现自定义配置多数据源;

该类中使用Map进行多数据源的存储,并根据key获取对应的数据源,并提供默认的数据源。


在实际获取连接的方法中,该类为我们提供一个获取key的抽象方法我们可以自己去实现业务。


②:创建一个ThreadLocal变量用于存储不同的数据源Key;

从如上的介绍中我们看出,因为我们需要实现上面的抽象方法以获得不同情况下给出不同的key,所以我们可以使用本地变量进行操作不用考虑线程安全的问题,在线程访问方法之前设置这一变量,而这里仅仅只需要取出变量即可。可以起到一个很好的存储过渡的作用。(关于ThreadLocal的增删这里不做描述,可参考之前的博客)

                           

③:使用AOP进行业务条件下的动态数据源设置;

最后,因为本文中我们假定select和insert分别使用不同的数据库,所以我们使用AOP在执行不同方法之前进行不同设置即可。

切面方法的伪代码如下:

                                    

最后在spring中进行AOP的配置,分别拦截seelct开头和insert开头的方法,配置不同的切面方法去设置不同的ThreadLocal值即可达到我们的要求。

              


④:根据不同的需求进行规范的代码编写,每一个业务要求不同,所以跟对自己的要求编写合理的代码是最重要的,主要是分享一下常规的思路,笔者也会不断发现更好的思路以分享给大家。

 
 
 

猜你喜欢

转载自blog.csdn.net/hewenbo111/article/details/80615870
今日推荐