package com.persagy.fm.mybatis.handler; import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; import com.baomidou.dynamic.datasource.creator.DruidDataSourceCreator; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; import com.persagy.fm.common.context.AppContext; import com.persagy.fm.common.helper.SpringHelper; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import java.sql.SQLException; import java.util.Set; /** * 动态数据源拦截器 * @author Charlie Yu * @date 2021-03-29 */ public class DynamicDataSourceHandler extends HandlerInterceptorAdapter { /** 忽略的url - swagger的文档不校验 */ private static final String[] IGNORE_URL = {".html", ".js", ".css", "/swagger-resources"}; @Autowired private DynamicRoutingDataSource dataSource; @Autowired private DruidDataSourceCreator dataSourceCreator; @Autowired private DynamicDataSourceProperties defaultProperty; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestURI = request.getRequestURI(); if (StringUtils.containsAny(requestURI, IGNORE_URL)) { return true; } resetDataSource(); return true; } /** * 多租户处理,数据源切换 */ private void resetDataSource() throws SQLException { // 是否启用多数据源 boolean isDynamic = SpringHelper.getBoolean("spring.datasource.dynamic.enabled", false); if(!isDynamic) { return; } // 默认为应用名 String dbNameDefault = SpringHelper.getString("spring.application.name"); String newDsName = AppContext.getContext().getGroupCode() + "_" + dbNameDefault; Set dsNames = dataSource.getCurrentDataSources().keySet(); if(!dsNames.contains(newDsName)) { // 取默认数据源 DataSourceProperty srcProperty = defaultProperty.getDatasource().get(dbNameDefault); // 设置新数据源 DataSourceProperty property = new DataSourceProperty(); BeanUtils.copyProperties(srcProperty, property); property.setPoolName(newDsName); property.setUrl(StringUtils.replace(property.getUrl(), dbNameDefault, newDsName)); // 创建数据源 DataSource currDs = dataSourceCreator.createDataSource(property); dataSource.addDataSource(newDsName, currDs); } // 设置当前数据源 DynamicDataSourceContextHolder.push(newDsName); } }