AbstractRoutingDataSource 实现切换数据源的原理

查看这个类可以发现。它继承了DataSource,那么找到他的getConnection方法

public Connection getConnection() throws SQLException {

return this.determineTargetDataSource().getConnection();
复制代码

}

protected DataSource determineTargetDataSource() {

Assert.notNull(this.resolvedDataSources, "DataSource router not initialized");Object lookupKey = this.determineCurrentLookupKey();DataSource 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 + "]");} else {return dataSource;}
复制代码

}

可以看出关键代码determineTargetDataSource中,这里处理了数据源切换,那么只需要写一个子类,将determineCurrentLookupKey这个方法重写下,即可做到数据源切换。

数据源配置

用到的部分代码如下,其余的用项目中的即可:

-数据库配置文件

#------------main MySQL ------------

hibernate.dialect=org.hibernate.dialect.MySQLDialect

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://47.94.18.202:3306/jxncpshop?useUnicode=true&characterEncoding=UTF-8

jdbc.username=root

jdbc.password=root

#------------main MySQL2 ------------

#openData.hibernate.dialect=org.hibernate.dialect.MySQLDialect

openData.jdbc.driver=com.mysql.jdbc.Driver

openData.jdbc.url=jdbc:mysql://47.94.18.202:3306/jnncpshop?useUnicode=true&characterEncoding=UTF-8

openData.jdbc.username=root

openData.jdbc.password=root

url1=http://www.jnncpshop.com:8081/

url2=http://www.jxncpshop.com:8081/

applicationContext.xml的配置

此处代码中需要主义的地方有:dataSource配置的key要和后面修改数据库是的名称保持一致,

-切换数据源和事务管理的先后顺序:这里通过order 来设置优先级,保证切换数据源的切面在事务管理之前

-sessionFactory配置注意的地方的地方:将默认的数据库配置取消,不然会无法切换

1:动态选择数据源 方法类

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**

  • Created by Administrator on 2019/1/16.

*/

public class ChooseDataSourceextends AbstractRoutingDataSource{

@Override

protected Object determineCurrentLookupKey() {
复制代码

String dataSource = HandleDataSource.getDataSource();

HandleDataSource.clearDataSource();//每次设置完清除,保证获取默认数据库

    return dataSource;
复制代码

}

}

2:数据源切换类

package com.ewebtd.eshop.admin.common;

/**

  • Created by Administrator on 2019/1/16.

*/

public class HandleDataSource {

// 数据源名称线程池,ThreadLocal是线程安全的,并且不能在多线程之间共享

public static final ThreadLocalholder =new ThreadLocal();
复制代码

public static void setDataSource(String dataSource){

holder.set(dataSource);

}

public static String getDataSource(){

return ((String)holder.get());

}

public static void clearDataSource() {

holder.remove();

}

}

3.数据源名称配置类

/**

  • 数据源配置名称--与配置文件中的key同名

  • Created by Administrator on 2019/1/16.

*/

public class DataSourceConst {

public static final StringDEFAULT ="default";

public static final StringSITE_MAIN ="siteMain";

}

4.自定义Filter实现根据域名去在每次请求前判断要选择的数据源

import com.ewebtd.eshop.admin.common.DataSourceConst;

import com.ewebtd.eshop.admin.common.HandleDataSource;

import javax.servlet.*;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.util.Properties;

/**

  • Created by Administrator on 2019/1/16.

*/

public class ChooseDataSourceFilterimplements Filter{

@Override

public void init(FilterConfig filterConfig)throws ServletException {
复制代码

}

@Override

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {
复制代码

if (!(servletRequestinstanceof HttpServletRequest) || !(servletResponseinstanceof HttpServletResponse)) {

throw new ServletException("OncePerRequestFilter just supports HTTP requests");

}

HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;

HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;

StringBuffer url = httpRequest.getRequestURL();

String tempContextUrl = url.delete(url.length() - httpRequest.getRequestURI().length(), url.length()).append("/").toString();

Properties properties =new Properties();

BufferedReader bufferedReader =new BufferedReader(new FileReader("E:/1227/source/trunk/eshop/eshopadmin/src/main/java/com/ewebtd/eshop/config/db.properties"));

properties.load(bufferedReader);

// if(tempContextUrl.equals("www.jnncpshop.com:8081/")){

    if(tempContextUrl.equals(properties.getProperty("url1"))){
复制代码

HandleDataSource.setDataSource(DataSourceConst.SITE_MAIN);

}else if(tempContextUrl.equals(properties.getProperty("url2"))){

HandleDataSource.setDataSource(DataSourceConst.DEFAULT);

}

filterChain.doFilter(servletRequest, servletResponse);

return;

}

@Override

public void destroy() {
复制代码

}

}

5.在web.xml中配置一下,过滤所有请求,注意在过滤器执行链的顺序

ChooseDataSourceFilter

com.ewebtd.eshop.admin.filter.ChooseDataSourceFilter

ChooseDataSourceFilter

/*

测试的话需要修改本机hosts文件,对127.0.0.1做域名映射,然后重启电脑

启动tomcat,效果如图:

转载于:https://juejin.im/post/5c773bb16fb9a049eb3c9d44

Spring+Hibernate 实现不同域名访问同一项目,自定义Filter根据域名选择对应的数据源...相关推荐

  1. 【javaWeb微服务架构项目——乐优商城day03】——(搭建后台管理前端,Vuetify框架,使用域名访问本地项目,实现商品分类查询,cors解决跨域,品牌的查询)

    乐优商城day03 0.学习目标 1.搭建后台管理前端 1.1.导入已有资源 1.2.安装依赖 1.3.运行一下看看 1.4.目录结构 1.5.调用关系 2.Vuetify框架 2.1.为什么要学习U ...

  2. 无公网域名,使用ngrok开启反向代理,实现公网域名访问本地项目

    文章目录 1. 下载 2. 使用 3. 创建项目 4. 本地访问 5. 域名访问 1. 下载 https://ngrok.com/download 根据不同的系统环境下载压缩包 2. 使用 windo ...

  3. html通过域名访问升级,HTML页面根据不同域名调用不同的JS文件

    有多个域名指向同一个主机空间,要实现用 www.abc.com 域名访问该网站的话,调用A.js,用www.def.com 域名访问该网站的话,调用B.js,其他域名访问则调用C.js. var st ...

  4. 服务器php网站配置域名访问,phpstudy在服务器上配置域名

    phpstudy在服务器上配置域名 内容精选 换一换 可以.一个服务器上可以同时配置多个证书.证书是与域名或IP绑定的,对服务器的数量没有限制.如果您购买的证书绑定的域名用于多台服务器,则购买的证书需 ...

  5. mysql配置域名访问_修改Host,配置域名访问

    Activity中获取view的高度和宽度为0的原因以及解决方案 在activity中可以调用View.getWidth.View.getHeight().View.getMeasuredWidth( ...

  6. houxiurong.com 关于Tomcat7部署 一台机器部署两个项目,一个用域名访问,一个用IP访问...

    该内容来自 http://houxiurong.com,转载请说明出处. 1.使用IP访问的项目放在Tomcat7 的webapps目录下面:比如:AAA 2.使用域名访问的项目放在Tomcat7的w ...

  7. ssh(Struts+spring+Hibernate)三大框架整合-简述

    ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...

  8. 快速通过nginx配置域名访问

    配置nginx进行域名访问文件 在nginx安装目录下的conf目录下新建一个配置文件,比如你新加的域名为admin.hello.com,你希望通过这个域名访问admin项目,那么新建一个admin. ...

  9. 使用域名访问后台页面

    使用域名访问本地项目 统一环境 我们现在访问页面使用的是:http://localhost:9001 有没有什么问题? 实际开发中,会有不同的环境: 开发环境:自己的电脑 测试环境:提供给测试人员使用 ...

最新文章

  1. FD.io/VPP — L3 vRouter
  2. C++将派生类赋值给基类(向上转型)(一)
  3. 基于Apache Thrift的公路涵洞数据交互实现原理
  4. python求偏度系数_用 Python 讲解偏度和峰度
  5. POJ 3468 A Simple Problem with Integers(线段树:区间更新)
  6. linux QT 结束当前进程_Qt编写控件属性设计器7-串口采集
  7. python arduino c_从Python向Arduino LCD发送一个字符串
  8. docker部署mysql项目_Docker部署项目步骤
  9. Java游戏编程——愤怒的小鸟(一)
  10. 基于JavaSwing开发医院信息管理系统 毕业设计 课程设计 大作业
  11. Kafka(zookeeper)环境配置超级详细
  12. openssl 签发证书相关命令
  13. Gap Statistic算法详解
  14. 简单的CSS3动画案例——奔跑的熊哥
  15. 直接下载 * http://softforspeed.51xiazai.cn/down/BaiduNetdisk_6.9.7.4.exe
  16. 开封文化艺术职业学院计算机甲骨文,甲骨文软件学院致19级全体同学的一封信 暨2021年寒假作业安排...
  17. 惊闻“漫游成本只有一分钱”
  18. 如何对PDF文件中的内容进行编辑修改
  19. 基于Labview的信号和噪声频带交错情况下的滤波系统设计
  20. 瓴羊DAAS闪耀云栖大会,发布数字化时代最优解

热门文章

  1. 【Paper】2020_离散多智能体系统的事件触发二分一致性研究_刘雨欣
  2. 医院如何选择HIS及电子病历系统
  3. 计算机硬盘写入错误怎么办,电脑提示缓存文件写入失败
  4. Vue2.0+ ts(TypeScript)常用装饰器
  5. openCV Python基础--镜像翻转和图像旋转
  6. windows11下vone客户端无法启动问题
  7. fgo1月23号服务器维护,FGO国服1月23日维护公告 终章最终决战开启
  8. python 读取图片,保存到指定目录,删除图片
  9. android屏幕灯光app,屏幕边缘LED灯光
  10. ubuntu-14.04.5-desktop-i386.iso