建立一个普通的接口
package com.tester.cls.design.mode; public interface IUser { public String getName(); public void setName(String name); public void setUser(int id,String name); public int getId(); public void setId(int id); }
构建一个实现类(简单的javaBean)
package com.tester.cls.design.mode; public class User implements IUser{ private int id; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void setUser(int id,String name) { setId(id); setName(name); } @Override public String toString() { return super.toString(); } }
实现代理
InvocationHandler实质是拦截器,用来拦截动态代理的方法调用。
Proxy才是动态代理,拦截器拦截Proxy生成的代理对象的方法
package com.tester.cls.design.mode; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class ObjectProxy implements InvocationHandler{ IUser delegateTarget = null; public IUser delegate(IUser delegateTarget) { this.delegateTarget = delegateTarget; return (IUser) Proxy.newProxyInstance(ObjectProxy.class.getClassLoader(), delegateTarget.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()+"-"+method.getReturnType()); return method.invoke(delegateTarget, args); } }
测试,测试一下
public static void main(String[] args) { User u = new User(); ObjectProxy objHandler = new ObjectProxy(); IUser delegate = objHandler.delegate(u); //注意,返回值的类型是注解类型 delegate.setUser(2014, "zhangsan"); System.out.println(delegate.getId()+"-"+delegate.getName()); System.out.println(u.getId()+"-"+u.getName()); u.setUser(2048, "张三"); System.out.println(delegate.getId()+"-"+delegate.getName()); System.out.println(u.getId()+"-"+u.getName()); }
输出结果
2014-zhangsan 2014-zhangsan 2048-张三 2048-张三
Cglib实现动态代理,Cglib的效率高于JDK动态代理,因为Cglib是有底层字节码方式生产一个代理类的(此观点来自于互联网,本人水平有限,目前只将概念)。
cglib使用底层ASM实现动态类的继承(很牛逼吧,我们日常使用的类是静态继承的,这简直是逆天的赶脚啊~~),能力好的童鞋建议去看源码。
(注:此处不提供 cglib.jar下载)
public class CglibProxy implements MethodInterceptor{ private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz){ //设置需要创建子类的类 enhancer.setSuperclass(clazz); enhancer.setCallback(this); //通过字节码技术动态创建子类实例 return enhancer.create(); } //实现MethodInterceptor接口方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("前置代理"); //通过代理类调用父类中的方法 Object result = proxy.invokeSuper(obj, args); System.out.println("后置代理"); return result; } }
测试如下,但不提供结果
public class DoCGLib { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); //通过生成子类的方式创建代理类 SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class); proxyImp.say(); } }
好了,这就是动态代理的基本认识
try doing it;