说实话,前一阵子一直被java的动态代理绕晕了,明明明白了是利用java的反射机制实现的,但就是会经常的忘记怎么去使用,写了就忘了,那种感觉就像明明都亲过吻了,但是却没有牵过手,这像话吗?于是我只好认真的想了想到底我是哪里出错了,原来发现是我的概念都没有搞清楚,所以用起来会不深刻。
如果要理解好动态代理,我觉得最好的话就是先理解好代理,当然前提是你知道了反射的一些使用技巧,不然还是先要理解好这个机制先。废话不多说,先介绍一下代理模式(普通的):
我觉得这样理解起来就比较好,比如你有一个很喜欢的女孩,你想要去表白,但是你比较害羞,所以准备写封情书先送上去,然而你自己又不敢去,所以这个时候你就很自然的叫你的朋友去送信。这样的话是不是真的说一句喜欢你不容易啊。其实这个就是代理的过程,那我们来看看代码的实现把:
(1)首先口SayLove(这个本来是你要去说的)
public interface SayLove {
void sayLoveXiaoMei();
void sayLoveXiaoHong();
}
(2)然后就是创建一个实现类:SayLoveImpl(本来话是要你去说的,但你的好朋友去做)
public class SayLoveImpl implements SayLove{
@Override
public void sayLoveXiaoMei() {
System.out.println("I Love XiaoMei");
}
@Override
public void sayLoveXiaoHong() {
System.out.println("I Love XiaoHong");
}
}
(3)运行来看看main(表白了)
public class main {
public static void main(String[] args) {
SayLove s = new SayLoveImpl();
s.sayLoveXiaoHong();
s.sayLoveXiaoMei();
}
}
这样我们就完成了一个很简单的代理了,理解了这个,然后我们来瞧瞧用java的反射机制来实现动态代理,其实也就是那么回事,只是在这里我们要明白的一个很重要的概念就是原对象(代理对象)相对于上面的例子其实就是你自己,然后另一个很重要的概念就是目标对象,就是帮你去做事情的人,(因为我们可以叫帮忙的朋友不单单是一个人吗)然后实现这个代理类,我们需要实现InvocationHandler接口,下面通过代码来看看把:
(1)
首先是接口不变:
public interface SayLove {
void sayLoveXiaoMei();
void sayLoveXiaoHong();
}
(2)
实现类也不需要改变哦
public class SayLoveImpl implements SayLove{
@Override
public void sayLoveXiaoMei() {
System.out.println("I Love XiaoMei");
}
@Override
public void sayLoveXiaoHong() {
System.out.println("I Love XiaoHong");
}
}
(3)我们要做的就是加一个代理的类
ProxySayLove
public class HandlerInvocation implements InvocationHandler {
private Object target;
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = method.invoke(target, args);
return obj;
}
}
(4)
运行结果看看是不是一样:
public class main {
public static void main(String[] args) {
// SayLove s = new SayLoveImpl();
// s.sayLoveXiaoHong();
// s.sayLoveXiaoMei();
SayLoveImpl s = new SayLoveImpl();
ProxySayLove p = new ProxySayLove();
SayLove ss = (SayLove) p.call(s);
ss.sayLoveXiaoHong();
ss.sayLoveXiaoMei();
}
}
好了,今天就讲到这里是,是不是很简单呢?只要想着表白这件事就ok的,不过前提是你是一个害羞的男孩,嘻嘻,这就是基于javaJDK的动态代理,下次我们在来讲讲基于CGLIB的,因为现在表了白,下次就是吃饭,看电影哦,当然也可以做其他的啦。