1. 本人实现代理类
public interface BizDemo { void helloGirl(String name); void helloBoy(String name);}public class BizDemoImpl implements BizDemo{ @Override public void helloGirl(String name) { System.out.println( name + "helloGirl in BizDemoImpl"); } @Override public void helloBoy(String name) { System.out.println( name + "helloBoy in BizDemoImpl"); }}public class BizDemoImplProxy implements BizDemo { private BizDemo real; BizDemoImplProxy(BizDemo real) { this.real = real; } @Override public void helloGirl(String name) { System.out.println("proxy by BizDemoImplProxy"); this.real.helloGirl(name); } @Override public void helloBoy(String name) { System.out.println("proxy by BizDemoImplProxy"); this.real.helloBoy(name); }}
public static void main(String[] args) { BizDemo demo = new BizDemoImpl(); demo.helloGirl("Lucy"); BizDemo demoProxy = new BizDemoImplProxy(demo); demoProxy.helloGirl("Lucy"); }//输入LucyhelloGirl in BizDemoImplproxy by BizDemoImplProxyLucyhelloGirl in BizDemoImpl
2. 用java动静代理生成类
- 首先让咱们忘掉对BizDemoImpl做代理,看看java主动生成代理类的成果
public class ProxyHandler implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy invoke." + args[0]); return null; }}
能够看到,只有有BizDemo这个接口,就能够通过java动静代理生成一个类,这个类领有接口BizDemo的所有办法,并且把所有办法调用,都透传到ProxyHandler的invoke办法中。
public static void main(String[] args) { Class[] inf = new Class[] {BizDemo.class}; BizDemo d = (BizDemo) Proxy.newProxyInstance(BizDemo.class.getClassLoader(), inf, new ProxyHandler()); d.helloGirl("javaDynamicProxy"); d.helloBoy("javaDynamicProxy boy");}//输入proxy invoke.javaDynamicProxyproxy invoke.javaDynamicProxy boy
只管咱们能够让java给咱们动静生成一个类,这个类实现了BizDemo接口,然而这样的类没有太多的实际意义。咱们的目标是代理BizDemoImpl,看看咱们是怎么达到的
- 让代理产生实际意义,对BizDemoImpl做代理
其实很简略,咱们只有把BizDemoImpl实例塞到ProxyHandler里,在invoke办法再调一次不就行了吗,于是咱们翻新创立一个Handler: ProxyHandler1
- 让代理产生实际意义,对BizDemoImpl做代理
public class ProxyHandler1 implements InvocationHandler { private BizDemo real; public ProxyHandler1(BizDemo real) { this.real = real; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("proxy invoke." + args[0]); if (method.getName().equals("helloBoy")) { this.real.helloBoy((String)args[0]); } else { this.real.helloGirl((String)args[0]); } return null; }}
public static void main(String[] args) { BizDemo demo = new BizDemoImpl(); Class[] inf = new Class[] {BizDemo.class}; BizDemo d = (BizDemo) Proxy.newProxyInstance(BizDemo.class.getClassLoader(), inf, new ProxyHandler1(demo)); d.helloGirl("javaDynamicProxy"); d.helloBoy("javaDynamicProxy boy");}//输入proxy invoke.javaDynamicProxyjavaDynamicProxyhelloGirl in BizDemoImplproxy invoke.javaDynamicProxy boyjavaDynamicProxy boyhelloBoy in BizDemoImpl
能够看到,动静代理生成的类,真正的代理了BizDemoImpl实例demo
单从上述例子看,用java动静代理,反而更简单类,要引入InvocationHandler和java.lang.reflect.Proxy,但认真想是有益处的,
第一,不论用户的interface有多少个办法,最终都代理收拢到InvocationHandler的invoke
第二,如果我的项目有很多interface要代理,代理类会成倍增加,难以保护
java动静代理类图如下,
$Proxxy0是java动静生成的类,这个类继承类Proxy实现了BizDemo接口,也就是上述的main中的d,对d的调用,先到$Proxy0, $Proxxy0委托给父类的Proxy的成员变量InvocationHandler 实例,即ProxyHandler1实例;而ProxyHandler1实例的invoke办法里最终调用了被代理的BizDemoImpl。
总之看起来很绕,框架类的代码往往就义直观来实现通用和简洁