黑马程序员技术交流社区

标题: 动态代理函数怎么理解 [打印本页]

作者: 朱明仁    时间: 2015-3-15 00:32
标题: 动态代理函数怎么理解
本帖最后由 朱明仁 于 2015-3-15 00:34 编辑

Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler(){。。。。。这里面InvocationHandler是作为内部类传入的,所在的代码黏贴在下面:

/*
* proxy4代理的可以是其他有接口的对象
*/
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;


public class test {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                ArrayList target=new ArrayList();
                Advice_1 advice=new MyAdvice_1();
                List proxy=(List)getProxy(target,advice);
                proxy.add(232);
                //System.out.println(proxy.isEmpty());
        }
        public static Object getProxy(final ArrayList target,final Advice_1 advice){
                Object proxy=Proxy.newProxyInstance(target.getClass().getClassLoader(),
                                target.getClass().getInterfaces(),
                                new InvocationHandler(){
                                       
                                        @Override
                                        public Object invoke(Object proxy, Method method,
                                                        Object[] args) throws Throwable {
                                                // TODO Auto-generated method stub
                                                advice.beforeMethod();
                                                long start=System.currentTimeMillis();
                                                Object retVal=method.invoke(target, args);
                                                long end=System.currentTimeMillis();
                                                //System.out.println(end-start+"  milliseconds");
                                                return retVal;
                                        }

                });
                return proxy;
        }

}
class MyAdvice_1 implements Advice_1{

        public void beforeMethod(){
                System.out.println("方法前输出。。。。。");
        }

}
interface Advice_1{
        public abstract void beforeMethod();
}

作者: 朱明仁    时间: 2015-3-15 00:35
然后还有这样一种创建代理的方法:Proxy.newProxyInstance(handler.getClass()
                                .getClassLoader(), realSub.getClass().getInterfaces(),// 传入realSub的字节码
                                handler);

作者: 朱明仁    时间: 2015-3-15 00:38
这是所在的代码:我该怎么理解所创建代理对象的这静态方法,类型一样也不是重载,但是传入的.class好像不太一样
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//1定义抽象角色
interface Subject {
        public void Request();

} // 2、定义真实角色 class RealSubject implements Subject {

class RealSubject implements Subject {
        @Override
        public void Request() { // TODO Auto-generated method stub
                System.out.println("RealSubject");
        }
} // 3、定义代理角色 class DynamicSubject

class DynamicSubject implements InvocationHandler {
        private Object sub;

        public DynamicSubject(Object obj) {
                this.sub = obj;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable { // TODO Auto-generated method stub
                System.out.println("Method:" + method + ",Args:" + args);
                method.invoke(sub, args);// 调用的是sub.Request(args)输出
                return null;
        }
}

// 通过Proxy.newProxyInstance构建代理对象
public class Prox {

        public static void main(String[] args) { // TODO Auto-generated method stub
                RealSubject realSub = new RealSubject();

                DynamicSubject handler = new DynamicSubject(realSub);// 实现的realSub
                // Class<?> classType = handler.getClass();
                // 本来是classType.getClassLoader()作为Proxy.newProxyInstance()的第一个参数

                Subject sub = (Subject) Proxy.newProxyInstance(handler.getClass()
                                .getClassLoader(), realSub.getClass().getInterfaces(),// 传入realSub的字节码
                                handler);
                System.out.println(sub.getClass());// 输出class $Proxy0

                sub.Request();// 通过调用代理对象的方法去调用真实角色的方法。调用的是DynamicSubject.invoke }

                // Invocationhandler +.invoke Proxy.newpProxyInstance(,,)
        }
}

作者: 朱明仁    时间: 2015-3-15 01:03
朱明仁 发表于 2015-3-15 00:35
然后还有这样一种创建代理的方法:Proxy.newProxyInstance(handler.getClass()
                                .getClassLoader(), rea ...

试了试,把这个handler替换成realSub也行,这是咋回事呢,这个handler也就是成员变量中有个realSub的实例
作者: 朱明仁    时间: 2015-3-15 09:46
我看网上都说,第一个参数是被代理对象的ClassLoader,第二个是被代理对象所实现的interface,第三个是代理类,可为什么第一个参数也可以是代理对实例的ClassLoader,这个可以是任意对象的ClassLoader的话就应该是上下文中的静态成员变量,显然不是
作者: 夏鹏    时间: 2015-3-15 11:18
动态代理 就是在方法调用前 调用你反射的方法 你 invoke 传入的方法的参数 你直接调用相当于 进入你改写的方法 你可以在这里添加你要的操作 你可以在它执行之前 或之后 而不改变原有的方法
你看到后面的切面编程想必就理解了
作者: 朱明仁    时间: 2015-3-15 16:26
夏鹏 发表于 2015-3-15 11:18
动态代理 就是在方法调用前 调用你反射的方法 你 invoke 传入的方法的参数 你直接调用相当于 进入你改写的 ...

好吧,你说的都理解了,切面编程还未听说过,呵呵,早晚也是要会的东西




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2