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

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,效果如图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值