使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持

Posted 李昊轩的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持相关的知识,希望对你有一定的参考价值。

本文紧接上一篇
独家首发! java助力mycat实现动态添加数据源, 实现SaaS新增租户秒登独立数据库
使用了动态代理来代理了jdbc的Connection, PreparedStatement对象,
是SaaS应用层实现的具体对接:
这个纯属我个人考虑开发效率搞的骚操作, 因为动态代理肯定是没有一个一个重写这种静态编译效率高, 希望给大家多一种解决思路~~

public class CGLIBProxyPreparedStatement 
    static String s = "executeupdate,executequery"; // 需要proxy的方法, 
    static Set<String> targetMethodNames = new HashSet(Arrays.asList(s.split(",")));

    static class CjLibProxy implements MethodInterceptor 
        private final PreparedStatement preparedStatement;

        public CjLibProxy(PreparedStatement preparedStatement) 
            this.preparedStatement = preparedStatement;
        

        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable 
            // 根据方法名判断是否追加hint注解
            if (targetMethodNames.contains(method.getName().toLowerCase())) 
                if (args.length >= 1) 
                    // sql 参数一定是在第一位的
                    args[0] = ProxySqlHints.renderHints(args[0].toString());
                
            
            return method.invoke(preparedStatement, args);
        
    

    public static PreparedStatement newInstance(PreparedStatement preparedStatement) 
        CjLibProxy proxy = new CjLibProxy(preparedStatement);
        return (PreparedStatement) Enhancer.create(PreparedStatement.class, proxy);
    

ProxySqlHints.renderHints() 这个方法不多说, 这里是实现增加sql改写的位置, 不同的中间件例如mycat sharding proxy都有不同的实现, 大概就是增加注解, 这里就不做举例了, 不会的同学可以私信或者下面评论答惑.

谢谢大家观看本文~~.

以上是关于使用CGLib动态代理jdbc原生类来实现应用层无感知的proxy层面的SaaS分库支持的主要内容,如果未能解决你的问题,请参考以下文章

Cglib方法实现动态代理

java动态代理之CGLIB实现

JDK动态代理和 CGLIB 代理

动态代理

java动态代理(JDK和cglib)

Java面试时,面试官常问的问题