美文网首页
[Java性能优化笔记]04 动态代理实现

[Java性能优化笔记]04 动态代理实现

作者: Kjiang | 来源:发表于2015-11-29 18:54 被阅读83次

    上一篇文章中,我们讲到了简单的代理模式实现。但是同时也产生了一个问题:假如我们需要代理的真实类中有很多方法,那么我们就要仿照真实类覆盖实现
    所有的方法。这使得我们的代码就有很多重复。但是我们可以使用简单的JDK动态代理的方式来实现。

    首先,假设我们的IDBQuery有如下实现:

    public interface IDBQuery {
        public String query();
        public String getName();
        public int getAge();
        public String getData();
    }
    

    然后在DBQuery中进行实现和打出简单的说明:

    public class DBQuery implements IDBQuery  {
    
        public DBQuery(){
            //start db connect
            try {
                Thread.sleep(1000);
                System.out.println("start db connect...");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public String query() {
            System.out.println("begin query...");
            return "begin query...";
        }
    
        @Override
        public String getName() {
            System.out.println("getName()...");
            return null;
        }
    
        @Override
        public int getAge() {
            System.out.println("getAge()");
            return 0;
        }
    
        @Override
        public String getData() {
            System.out.println("getData()");
            return null;
        }
    }
    

    接下来我们创建DBQueryInvocationHandler:

    public class InvocationDBQueryHandler implements InvocationHandler {
        
        private DBQuery dbQuery = null;
        
        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            if(dbQuery == null){
                dbQuery = new DBQuery(); //如果第一次被调用才生成真实对象
            }
            String methodName = method.getName();
            System.out.println("called method name:" + methodName);
            return method.invoke(dbQuery, args);//转调真实方法
        }
    
        public static IDBQuery createJdkDBQuery(){
            IDBQuery idbq = (IDBQuery) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
                    new Class[]{IDBQuery.class}, new InvocationDBQueryHandler());
            return idbq;
        }
    }
    

    以下是测试:

    IDBQuery jdkIdbq = InvocationDBQueryHandler.createJdkDBQuery();
    System.out.println("after create jdkDBQuery");
    jdkIdbq.query();
    jdkIdbq.getAge();
    jdkIdbq.getName();
    jdkIdbq.getData();
    

    得到如下输出结果:

    after create jdkDBQuery
    start db connect...
    called method name:query
    begin query...
    called method name:getAge
    getAge()
    called method name:getName
    getName()...
    called method name:getData
    getData()
    

    从结果可以看出:
    就像上一篇的DBQueryProxy一样,我们仅在query方法或其他方法被调用时才初始化DBQuery

    这种动态代理的方法简单快速的实现了我们需要延迟加载DBQuery的需求。其实动态代理的常用场景是日志记录和
    业务分离,例如Spring Framework中的AOP。使用动态代理我们可以在被调用方法的前后执行我们需要的操作。

    于2015-06-07

    相关文章

      网友评论

          本文标题:[Java性能优化笔记]04 动态代理实现

          本文链接:https://www.haomeiwen.com/subject/dpqjhttx.html