Filter 切换数据源
目标:拦截以 filter/**开头的所有请求,如果后面的方法以 a 开头就切换到 db1,以 b 开头就切换到 db2,其余使用默认数据源。
实现如下:
@Slf4j
@WebFilter(filterName = "dsFilter", urlPatterns = {"/filter/*"})
public class DynamicDatasourceFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("loading filter {}", filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String requestURI = request.getRequestURI();
log.info("经过多数据源filter,当前路径是{}", requestURI);
// String headerDs = request.getHeader("ds");
// Object sessionDs = request.getSession().getAttribute("ds");
String s = requestURI.replaceFirst("/filter/", "");
String dsKey = "master";
if (s.startsWith("a")) {
dsKey = "db1";
} else if (s.startsWith("b")) {
dsKey = "db2";
} else {
}
//执行
try {
DynamicDataSourceContextHolder.push(dsKey);
filterChain.doFilter(servletRequest, servletResponse);
} finally {
DynamicDataSourceContextHolder.poll();
}
}
@Override
public void destroy() {
}
}
@SpringBootApplication
@ServletComponentScan //filter必须使用这个
@MapperScan("com.baomidou.samples.ds.mapper")
public class AllDataSourceApplication {
public static void main(String[] args) {
SpringApplication.run(AllDataSourceApplication.class, args);
}
}
示例项目(原 all-datasource-sample 已随示例仓库重构调整,可参考本文完整代码): https://github.com/dynamic-datasource/dynamic-datasource-samples 扩展:从 request 中还能获取到很多东西,如 header 和 session,是否同理可以根据自己业务需求根据 header 值和 session 里对应的用户来动态设置和切换数据源?