通过java反射让JVM自动的创建动态代理类

来源:互联网 发布:批量重命名软件 编辑:程序博客网 时间:2024/06/07 04:52
import java.lang.annotation.Target;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;/** * @author Dqd *ClassLoader loader ----指定被代理对象的类加载器Class[] Interfaces ----指定被代理对象所实现的接口InvocationHandler h ----指定需要调用的InvocationHandler对象 * */public class ProxyTest {public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {Class classProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);System.out.println(classProxy1.getName());System.out.println("构造参数列表为");Constructor[] con = classProxy1.getConstructors();for(Constructor co : con){String str = co.getName();StringBuilder sb = new StringBuilder(str);sb.append("(");Class[] para = co.getParameterTypes();for(Class pa:para){sb.append(pa.getName()).append(',');}if(para!=null && para.length!=0){sb.deleteCharAt(sb.length()-1);}sb.append(")");System.out.println(sb.toString());}System.out.println("方法列表为");Method[] con1 = classProxy1.getMethods();for(Method co : con1){String str = co.getName();StringBuilder sb = new StringBuilder(str);sb.append("(");Class[] para = co.getParameterTypes();for(Class pa:para){sb.append(pa.getName()).append(',');}if(para!=null && para.length!=0){sb.deleteCharAt(sb.length()-1);}sb.append(")");System.out.println(sb.toString());}System.out.println("创建对象实例");//因为代理对象的构造函数没有无参的所以下面代码运行会有异常//Object obj = (Object)classProxy1.newInstance();Constructor constructor = classProxy1.getConstructor(InvocationHandler.class);//其中的InvocationHandler是一个接口所以要通过子类去实现class MyInvocationHandler1 implements InvocationHandler{@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}}Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler1());//注意如果直接输出proxy1代理对象创建的实现会输出null,但是这里的null可能是proxy1对象创建的有问题本身就是nul//另一种情况就是对象的toString()返回的是一个nullSystem.out.println(proxy1.toString()+"通过有构造参数创建的");proxy1.clear();//如果调用下面有返回值的函数就会报错//proxy1.size();//由于proxy1使用内部类进行生成的只用了一次//所以我们可以直接的new Interface(){}(既匿名内部类)Collection proxy2 =(Collection) constructor.newInstance(new InvocationHandler(){@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubreturn null;}});//将目标(既ArrayList)抽取成为一个对象System.out.println("-------开始运行代理类------");final ArrayList al = new ArrayList();//方Myadvice是系统功能,和过程代码分离,灵活了AOPCollection proxy3 = (Collection)getProxy(al,new MyAdvice());proxy3.add("zxc");proxy3.add("345");System.out.println(proxy3.size());}private static Object getProxy(final Object target,final Advice advice) {Object proxy3 = (Object)Proxy.newProxyInstance(target.getClass().getClassLoader(),//new Class[]{Collection.class},target.getClass().getInterfaces(),new InvocationHandler() {//分别是对象,方法,参数@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {/*long bt = System.currentTimeMillis();//将调用的方法关联起来Object retVal = method.invoke(target, args);for (int i = 0; i <10; i++) {}long et = System.currentTimeMillis();System.out.println(method.getName()+" "+ (et - bt )+"hehe");return retVal;*///直接调用方法advice.beforeMethod(method);//将调用的方法关联起来Object retVal = method.invoke(target, args);for (int i = 0; i <10; i++) {}advice.afterMethod(method);return retVal;}});return proxy3;}}

0 0