概念:
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
JDK的动态代理用起来非常简单,当它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包。
JDK动态代理实现
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest {
static StringBuilder sBuilder=new StringBuilder();
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//代理类字节码
Class clazzProxy1= Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
//代理类构造方法列表,没有无参构造方法
System.out.println("...........begin constructors list............");
Constructor[] constructors= clazzProxy1.getConstructors();
for(Constructor constructor:constructors){
StringBuilder sBuilder=new StringBuilder();
sBuilder.append(constructor.getName()).append("(");
Class[] clazzparams =constructor.getParameterTypes();
for(Class clazzparam:clazzparams){
sBuilder.append(clazzparam.getName()).append(",");
}
if(clazzparams.length!=0){
sBuilder.deleteCharAt(sBuilder.length()-1);
}
sBuilder.append(")");
System.out.println( sBuilder.toString());
}
//代理类方法列表
System.out.println("...........begin methods list............");
Method[] methods= clazzProxy1.getMethods();
for(Method method:methods){
StringBuilder sBuilder=new StringBuilder();
sBuilder.append(method.getName()).append("(");
Class[] clazzparams =method.getParameterTypes();
for(Class clazzparam:clazzparams){
sBuilder.append(clazzparam.getName()).append(",");
}
if(clazzparams.length!=0){
sBuilder.deleteCharAt(sBuilder.length()-1);
}
sBuilder.append(")");
System.out.println( sBuilder.toString());
}
//通过字节码创建代理类的实例,不能用newInstance(),构造方法传入InvocationHandler
System.out.println("...........begin create instance object............");
Constructor constructor=clazzProxy1.getConstructor(InvocationHandler.class);
Collection proxy1= (Collection) constructor.newInstance(new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
System.out.println(proxy1);
proxy1.clear();//无返回值的方法成功
//一步到位创建代理类实例
Collection proxy2=(Collection) Proxy.newProxyInstance(Collection.class.getClassLoader(),new Class[]{Collection.class}, new InvocationHandler(){
ArrayList target=new ArrayList<>();//被代理对象,目标对象
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
long begintime=System.currentTimeMillis();
Object retVal=method.invoke(target, args);
long endtime=System.currentTimeMillis();
System.out.println(method.getName()+" running time is " +(endtime-begintime));
return retVal;
}
});
proxy2.add("lhm");
proxy2.add("zxx");
proxy2.add("bxd");
System.out.println(proxy2.size());
System.out.println(proxy2.getClass().getName());
}
}本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1719600
java动态代理实现Proxy和InvocationHandler
原文:http://tianxingzhe.blog.51cto.com/3390077/1719600