下面通过一个简单的DEMO,来探究一下java.lang.reflect是如何实现代理模式的,重点在main方法上,我们明明为flyImpl实现类的wing(String)赋值为null,但是最终的输出结果中,却发现这个flyImpl对象的fly域变成了“A injected swing value....”,这一切是如何发生的呢?
首先,定义一个接口类,fly,它具有两个方法,一个而是addWing,一个是fly。
package com.ziwen.vo; public interface Flyable { public void addWing(String wing); public String fly(); }
编写一个实现类,LittleBird实现Flyable。
package com.ziwen.vo; public class LittleBird implements Flyable { private String wing; public String getWing() { return wing; } public void setWing(String wing) { this.wing = wing; } @Override public void addWing(String wing) { setWing(wing); } @Override public String fly() { return "wing:"+getWing()+"...fly"; } }
package com.ziwen.vo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class ObjectHandler implements InvocationHandler { private Object target; public ObjectHandler(Object object){ this.target = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if("addWing".equals(method.getName())){ args[0]="A injected swing value."; } return method.invoke(target, args); } }
最后,编写一个工厂方法,用于获取代理类,简便起见,将main方法也写在里面。
package com.ziwen.vo; import java.lang.reflect.Proxy; public class FlyFactory { public static Flyable getFlayImpl() { Flyable fly = new LittleBird(); return (Flyable) Proxy.newProxyInstance( fly.getClass().getClassLoader(), new Class[] { Flyable.class }, new ObjectHandler(fly)); } public static void main(String[] args) { Flyable fly = FlyFactory.getFlayImpl(); fly.addWing(null); System.out.println(fly.fly()); } }
核心类说明:
JDK提供了一个类,名字叫做Proxy.newProxyInstance(1,2,3)。其中,第一个参数是用于规定使用哪一个类的加载器?第二个参数是实现了哪些接口的数组,第三个参数是描述调用和它关联的一个invocationHandler的类型的对象。
任何一个动态代理对象都要关联一个invocationHandler对象,只有这个对象才知道要代理什么事情。代理对象会调用invocationHandler中的invoke方法,这个invoke方法是被动态代理对象调用的,这样我们就可以扩展invoke方法,实现很多我们想做的事情。