jdK动态代理

jdK动态代理

在日常的编程中我们需要处理诸如日志,事务,统计时间等的操作。

拿计算方法的运行时间来举例子

定义一个coder接口

package fun.javaweb;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:22
 */
public interface Coder {

    void writeBug();

}

实现类

package fun.javaweb;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:24
 */
public class AshinLee implements Coder {

    @Override
    public void writeBug() {
        System.out.println("write a bug");  
    }
}

这时我们如果要计算时间,就会在运行的方法中加入相应的代码

package fun.javaweb;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:24
 */
public class AshinLee implements Coder {

    @Override
    public void writeBug() throws InterruptedException {
        long begin = System.currentTimeMillis();
        Thread.sleep(1000); //emm... 一秒一个bug
        System.out.println("write a bug");
        long end = System.currentTimeMillis();
        System.out.println("cost time :" + (end - begin));
    }
}

进行测试:

package fun.javaweb;

import org.junit.Test;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:27
 */
public class TestJdkDynamicProxy {

    @Test
    public void test() throws InterruptedException {
        Coder coder = new AshinLee();
        coder.writeBug();
    }
}
result:
write a bug
cost time :1000

如果就这一个方法的话还好,改变下记录日志的逻辑很方便,可是在真实的项目中有成百上千的类,如果都需要手动改每一个位置的那么简直就是灾难了,好了,加班吧~

这时候就该引入动态代理了,动态代理让我们只需要改变一处的逻辑。

我们需要实现 InvocationHandler 并重写方法

package fun.javaweb;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:33
 */
public class CoderProxy implements InvocationHandler{

    private Object target; //被代理对象

    public CoderProxy(Object object){
        this.target = object;
    }

    //传入被代理对象的类加载器和接口,jdk动态代理是通过接口进行代理的,this为实现InvocationHandler的对象
    public Object getTarget() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //将记录花费时间的逻辑从原先的coder实现类中移到这里。
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long begin = System.currentTimeMillis();
        Thread.sleep(1000);
        //传入被代理对象和方法参数,method为实际被调用的方法
        Object o  = method.invoke(target,args);
        long end = System.currentTimeMillis();
        System.out.println("cost time :" + (end - begin));
        return o;
    }
}

测试

package fun.javaweb;

import org.junit.Test;

/**
 * @author ashinlee
 * @date 2018/4/7
 * @time 22:27
 */
public class TestJdkDynamicProxy {

    @Test
    public void test() throws InterruptedException {
        //这边可随意更换实现类的对象,例如:
        //  Coder coder = (Coder) new CoderProxy(new Ben()).getTarget();
        Coder coder = (Coder) new CoderProxy(new AshinLee()).getTarget();
        coder.writeBug();
    }
}
result:
write a bug
cost time :1001

以上就是jdk的动态代理。

想一起交流或者有问题的朋友可以关注我的公众号,里面有群聊连接可以一起交流遇到的问题,如果失效可以后台回复我,每天会同步更新
博客连接 : AshinLee’s blog

公众号:
这里写图片描述

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页