职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 286|回复: 1

Proxy Pattern

[复制链接]
木已 发表于 2011-8-25 10:14 | 显示全部楼层 |阅读模式
动态代理(Dynam......
推荐链接 见证又一个......


动态代理(Dynamic Proxy)
在了解动态代理之前先来简单的回顾下代理模式
一、代理的概念:生活中的代理不胜枚举,譬如你想买一台ipad2(其实我也想买)你肯定不希望跑到美国苹果的总部买回来,多麻烦啊!一般都是希望直接在国内的苹果代理商那里去购买。这样的好处就是节省了不少时间和金钱,当然还避免的很多风险(风险都由代理商帮你完成了)。设计模式中的代理也如同生活中的代理,客户端不直接引用真实对象,而是去引用他的代理对象,由代理对象完成真实对象所要做的一些事情。
二、代理对象所涉及角色:
1.  抽象主题角色:声明抽象主题和代理主题的共同接口,这样可以在使用真实主题角色的地方同时也可以使用代理角色。抽象主题角色一般是接口或者抽象类
2.  真实主题角色:
3.  代理主题角色:通常代理角色包含有真实主题角色的引用,以便操作真实主题对象。因为与真实主题角色有共同的接口,这样可以替代真实主题,通常代理主题不单单处理客户调用传递过来的请求给真实主题,而且会包含一些其他的操作(好比例子中的风险处理就有代理去解决)。
三、代理的类图:

四、代码清单:
RealSubject.java
Java代码  
/**  
*真实主题对象   
*/  
public class RealSubject extends Subject {   
  
    @Override  
    public void request() {   
        System.out.println("realSubject request...");   
    }   
      
}  

/**
*真实主题对象
*/
public class RealSubject extends Subject {

        @Override
        public void request() {
                System.out.println("realSubject request...");
        }
       
}


Subject.java
Java代码  
/**  
* 抽象主题角色  
*  
*/  
public abstract class Subject {   
      
    public abstract void request();   
      
}  

/**
* 抽象主题角色
*
*/
public abstract class Subject {
       
        public abstract void request();
       
}

Proxy.java
Java代码  
public class Proxy extends Subject{   
  
    private RealSubject realSubject;   
      
    public Proxy(RealSubject realSubject) {   
        this.realSubject = realSubject;   
    }   
    private void beforeRequest(){   
        System.out.println("proxy beforeRequest");   
    }   
    @Override  
    public void request() {   
        beforeRequest();   
        realSubject.request();   
        afterRequest();   
    }   
  
    private void afterRequest(){   
        System.out.println("proxy afterRequest");   
    }   
}  

public class Proxy extends Subject{

        private RealSubject realSubject;
       
        public Proxy(RealSubject realSubject) {
                this.realSubject = realSubject;
        }
        private void beforeRequest(){
                System.out.println("proxy beforeRequest");
        }
        @Override
        public void request() {
                beforeRequest();
                realSubject.request();
                afterRequest();
        }

        private void afterRequest(){
                System.out.println("proxy afterRequest");
        }
}


五、动态代理:
正式进入主题,现在又这样的一个需求,系统中有一百个类真实主题对象,要为其手动的添加代理类可以想象是一个多大的工程。从jdk1.3开始,引入了动态代理,java.lang.reflect.Proxy,JVM可以自己创建代理类,这样不尽提高了效率,而且更灵活。
动态代理三个主要的类:
Proxy,InvocationHandler,Method
Proxy类中主要三个方法:
protected Proxy(InvocationHandler h)

public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)

public static Object newProxyInstance(ClassLoader loader,
                    Class<?>[] interfaces,
                    InvocationHandler h)
1.  分析getProxyClass方法:既然是由JVM创建代理类,首先就必须为其制定ClassLoader,因为所有类都需要类加载器去加载。创建代理的目的是做为客户端和目标对象(真是主题对象)之间的一个中介,所以要为代理类指定一些方法,这里所采用的实现方式就是为其指定一个或者多个接口,JVM生成该代理类时自动的实现这些接口中的方法。这个代理类仅能用作具有相同接口的目标类的代理。
2.  InvocationHander:调用处理器,他是一个接口,就申明了一个invoke方法
public Object invoke(Object proxy, Method method, Object[] args)
每一个代理实例都必须指定一个调用处理器,代理对象调用方法时,该方法会指派到调用处理器的invoke()中去。代理的方法封装成invoke中的method对象,其中的参数封装成Object[]
代码清单:
Java代码  
public class ProxyTest {   
      
    @SuppressWarnings("unchecked")   
    public static void main(String[] args) {   
           
        Collection collection = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {   
            ArrayList list = new ArrayList();   
            public Object invoke(Object proxy, Method method, Object[] args)   
                    throws Throwable {   
                System.out.println("方法:"+method.getName()+"   参数:"+Arrays.toString(args));   
                return method.invoke(list, args);   
            }   
        });   
        collection.add("aaa");   
        collection.add("aaa");   
        collection.add("aaa");   
        collection.add("aaa");   
        System.out.println(collection.size());   
    }   
}  

public class ProxyTest {
       
        @SuppressWarnings("unchecked")
        public static void main(String[] args) {
               
                Collection collection = (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader(), new Class[]{Collection.class}, new InvocationHandler() {
                        ArrayList list = new ArrayList();
                        public Object invoke(Object proxy, Method method, Object[] args)
                                        throws Throwable {
                                System.out.println("方法:"+method.getName()+"   参数:"+Arrays.toString(args));
                                return method.invoke(list, args);
                        }
                });
                collection.add("aaa");
                collection.add("aaa");
                collection.add("aaa");
                collection.add("aaa");
                System.out.println(collection.size());
        }
}

输出结果:
方法:add   参数:[aaa]
方法:add   参数:[aaa]
方法:add   参数:[aaa]
方法:add   参数:[aaa]
方法:size   参数:null
4
六、     AOP原理:http://www.iteye.com/topic/336873
利用动态代理知识可以直接模拟一个aop
Advice.java
Java代码  
public interface Advice {   
    public void before();   
    public void after();   
}  

public interface Advice {
        public void before();
        public void after();
}

MyProxy.java
Java代码  
public class MyProxy {   
      
    public Object getProxy(final Object target,final Advice advice){   
           
        Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {   
               
            @Override  
            public Object invoke(Object proxy, Method method, Object[] args)   
                    throws Throwable {   
                advice.before();   
                Object obj = method.invoke(target, args);   
                advice.after();   
                return obj;   
            }   
        });   
        return object;   
    }   
}  

public class MyProxy {
       
        public Object getProxy(final Object target,final Advice advice){
               
                Object object = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), new InvocationHandler() {
                       
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args)
                                        throws Throwable {
                                advice.before();
                                Object obj = method.invoke(target, args);
                                advice.after();
                                return obj;
                        }
                });
                return object;
        }
}

大小: 14.5 KB
查看图片附件

话说我当年 发表于 2011-8-25 10:14 | 显示全部楼层
推荐链接
见证又一个准百万富翁的诞生!
20-30万急聘多名天才Java/MTA软件工程师

3G培训就业月薪平均7K+,不3K就业不花一分钱!

您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-9 07:11 , Processed in 0.149631 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表