A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黎志文 中级黑马   /  2013-7-21 07:34  /  1008 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨兴庭 于 2013-7-22 21:29 编辑

类加载器和代理看了很多遍,仍然只是懵懂地明白一点点,没有一点思路,好着急,好挫败...
在学习代理时,有两个问题比较纠结:
1.InvocationHandler中的invoke(Object proxy,Method method,Object[] orgs)方法,它的第一个参数接收一个代理对象,这有什么意义?
这个方法内部好像不会用到这个代理对象?

2.代理是为了获取一些接口的方法,那这样为何不干脆实现这个接口得了?

评分

参与人数 1黑马币 +3 收起 理由
杨兴庭 + 3 赞一个!

查看全部评分

2 个回复

倒序浏览
确实是用不上第一个参数,仅仅是为了覆盖,
就是要求子类方法的签名(名称与参数),返回类型与祖先类的保持一致才能实现。
代理是为了获取一些接口的方法,那这样为何不干脆实现这个接口得了?
那就可能又回到静态代理了。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
1.        第一个参数接受的是实现InvocationHandler接口的这个代理类对象,一般用不上,我们不用去管它。
2.        代理模式一般涉及到的角色有
(1)        抽象角色:声明真实对象和代理对象的共同接口。接口声明了这两个角色相同的操作,这样,代理就能以与真实对象相同的方式来与用户交互。
(2)        代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象。同时代理对象提供与真实对象相同的接口,这样在任何时刻都能代替真实对象。代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装
(3)        真实角色:代理角色所代表的真实对象,是我们最终引用的对象。
我们来举个例子:
下面是抽象角色:
public interface Subject
{
        public void request();
}
下面是真实角色:
public class RealSubject implements Subject
{
        public void request()
        {
                System.out.println("From real subject!");
        }

}
下面是我们的动态代理角色:
public class DynamicSubject implements InvocationHandler
{
        private Object sub;
       
        public DynamicSubject(Object obj)
        {
                this.sub = obj;
        }
       
        public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable
        {
                System.out.println("before calling: " + method);
               
                method.invoke(sub, args);
               
                System.out.println(args == null);
               
                System.out.println("after calling: " + method);
               
                return null;
        }
}
        下面是我们的客户端
public class Client
{
        public static void main(String[] args)
        {
                RealSubject realSubject = new RealSubject();

                InvocationHandler handler = new DynamicSubject(realSubject);

                Class<?> classType = handler.getClass();

                // 下面的代码一次性生成代理

                Subject subject = (Subject) Proxy.newProxyInstance(classType
                                .getClassLoader(), realSubject.getClass().getInterfaces(),
                                handler);

                subject.request();

                System.out.println(subject.getClass());

        }
}
上面代码中realSubject.getClass().getInterfaces()就是我们所说的抽象角色。程序通过这个接口知道需要进行的操作。生成代理对象中,第一个参数是类加载器,第三个参数是InvocationHandler对象,这样就可以通过传入的这些参数动态地生成代理。而不是针对每一个真实角色,都要有一个对应的代理,这样的话,会导致产生大量的类,这就是需要动态代理的原因。
其实,代理可以理解成中介,比如,我们找兼职,不知道哪里有工作,所以通过中介来找工作。但最终还是要到用人单位去工作,而不是中介,所以中介要有一个用人单位的引用,实际操作时还是要让用人单位来提供工作,中介不能完成这个动作。希望能够帮助到你。

评分

参与人数 1技术分 +1 收起 理由
杨兴庭 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马