1.使用java jdk Proxy实现动态代理,该原理是反射机制。
建立一个普通的接口
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-张三
2.使用cglib.jar实现动态代理,原理是操作底层字节码
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;
来源:oschina
链接:https://my.oschina.net/u/2256215/blog/338821