通过之前的静态代理可以发现,静态代理比较死板,是编译期code好代理对象代码,再由jvm转换成字节码,代理对象就已经存在了。
而且,每个对象都要自定义一个自己的一个代理对象。
而动态代理,则是通过了java的反射机制,在程序的运行期动态的活的代理对象。
下面看个小例子吧:
1、上层接口 package com.cn.proxy; /** * Created by xieguoliang on 16/3/17. * 代理和被代理类接口 */ public interface IClothProduct { int createCloth(); } 2、接口实现类
package com.cn.proxy; /** * Created by xieguoliang on 16/3/17. */ public class NikeProduct implements IClothProduct { @Override public int createCloth() { System.out.print("nike生产衣服"); return 1; } } 3、动态代理类生成对象
package com.cn.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by xieguoliang on 16/3/17. */ public class ProxyProduct implements InvocationHandler { private Object target; /** * 绑定代理类 并返回一个代理对象 * @param target * @return */ 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 { System.out.print("进入代理类----"); //执行并且返回值 Object o = method.invoke(target, args); System.out.print("代理类执行完毕"); return o; } } 4、测试类
package com.cn.proxy; /** * Created by xieguoliang on 16/3/17. */ public class ProxyTest { public static void main(String[] args) { ProxyProduct p = new ProxyProduct(); IClothProduct n = (IClothProduct) p.bind(new NikeProduct()); int a = n.createCloth(); System.out.print(a); } }
jvm的动态代理,有一个限制,就是必须依赖与接口,另外一种cglib动态代理则解决了这一弊端。 cglib动态代理
2、接口实现类
package com.cn.proxy; /** * Created by xieguoliang on 16/3/17. 没有接口 */ public class NikeProduct{ @Override public int createCloth() { System.out.print("nike生产衣服"); return 1; } } 3、动态代理类生成对象
package com.cn.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by xieguoliang on 16/3/17. */ public class ProxyProduct implements InvocationHandler { private Object target; /** * 绑定代理类 并返回一个代理对象 * @param target * @return */ public Object bind(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.print("进入代理类----"); //执行并且返回值 Object o = method.invoke(target, args); System.out.print("代理类执行完毕"); return o; } } 4、测试类
package com.cn.proxy; /** * Created by xieguoliang on 16/3/17. */ public class ProxyTest { public static void main(String[] args) { ProxyProduct p = new ProxyProduct();
NikeProduct n = (NikeProduct) p.bind(new NikeProduct());
int a = n.createCloth(); System.out.print(a); } }