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
公众号: