`
H.Z
  • 浏览: 16747 次
  • 来自: 长沙
社区版块
存档分类
最新评论

代理模式

 
阅读更多

1.什么是代理模式

    代理:出发点到目的地中间隔了一层,这一层叫代理.

    代理一般作用是预处理消息,过滤消息,消息转发给委托类.

    代理类是接活的,委托类是干活的,它们都有同一个接口.

 

 

2.代理类分类

    静态代理:写死的,已经存在的class.

    动态代理:活的,在程序运行时,反射机制动态创建生成的.

 

3.静态代理

    分基于接口的静态代理和基于继承的静态代理.

    (1)基于接口的静态代理.个人感觉就是装饰器模式的一种:

        <1>.先定义接口,父亲的能力eat()吃东西.     

1
        2
3
4
5
//基于接口的静态代理,
public interface Father {
 
    public void eat();
}

 

        <2>.儿子类继承了父亲类,并学习了父亲的吃饭能力.                   

 

1
        2
3
4
5
6
7
public class Son implements Father {
 
    @Override
    public void eat() {
        System.out.println("儿子吃饭了");
    }
}

 

 

        <3>.但是儿子太小了,不能自己动手吃饭,这时需要给儿子找个代理(妈妈),帮助儿子吃饭.

           

1
2
3
4
5
       6
7
8
9
10
11
12
13
14
15
16
17
18
//代理对象(接活的)
public class SonProxyMaM implements Father{
     
    //维护委托类(真正干活的)对象
    private Son son;
     
    public SonProxyMaM(Son son){
        this.son=son;
    }
 
    @Override
    public void eat() {
        System.out.println("妈妈给儿子喂饭");
        son.eat();
        System.out.println("妈妈给儿子擦嘴");
    }
 
}

 

          真正需要吃饭的是儿子,所以妈妈里面必须要有儿子,妈妈只是代理工作,辅助儿子吃完饭.

 

        <4>测试      

1
2
      3
4
5
6
7
8
public class Main {
 
    public static void main(String[] args) {
        Son son=new Son();//委托类(干活的)
        Father f=new SonProxyMaM(son);//代理对象(接活的)
        f.eat();
    }
}


        <5>结果

        

 

 

 

 

    (2)基于继承的代理模式

        其实这种方式更相当于方法的重写.

 

        总之,静态代理是硬编码,在编码的时候就要知道委托类的类型.

 

 

4.动态代理

     一.JDK1.3的Proxy代理,其委托类必须有接口.

     二.CGLB能对类实现进行代理

    

    (1)JDK的Proxy代理.

         首先看看API:

1
2
      3
4
5
6
7
8
9
10
11
12
13
/** 
     * </pre> 
     * @param loader  类加载器,用来加载委托类(目标对象)class信息 
     * @param interfaces  委托类(目标对象)的接口,通过接口信息来创建动态代理类 
     * @param h  代理实例的调用处理程序,生成的代理类里面的所有方法,都会统一跳转到invoke方法中. 
     * @return 
     * @throws IllegalArgumentException 
     * </pre> 
     */  
    @CallerSensitive  
    public static Object newProxyInstance(ClassLoader loader,  
                                          Class<?>[] interfaces,  
                                          InvocationHandler h) 

 

        Proxy的一个静态方法生成代理对象.通过参数loader和interfaces,在Proxy里面反射出代理对象的Class文件.

        然后根据Class文件创建生成代理对象实例,然后通过该实例将目标对象的方法指派到InvocationHandler接

       口的invoke方法.我们所需要的业务逻辑需实现InvocationHandler接口,实现invoke方法,此时目标对象的

       方法就可以额外的添加功能,过滤请求等代理操作了.

 

1
2
3
4
5
      6
7
8
9
10
11
12
13
14
public interface InvocationHandler {  
       
    /** 
     * </pre> 
     * @param proxy :运行时动态生成的代理类 
     * @param method :目标对象的方法 
     * @param args :目标对象方法的参数 
     * @return :返回代理类对象实例 
     * @throws Throwable 
     * </pre> 
     */  
    public Object invoke(Object proxy, Method method, Object[] args)  
        throws Throwable;  

 

        具体的源码可查:http://jingbo2759.blog.163.com/blog/static/98375315201042111517803/

 

        <1>继续上述静态代理的例子.父亲有吃饭能力.

1
        2
3
4
5
//基于接口的动态代理,
public interface Father {
 
    public void eat();
}

 

 

        <2>儿子继承了父亲的吃饭能力.

 

1
        2
3
4
5
6
7
public class Son implements Father {
 
    @Override
    public void eat() {
        System.out.println("儿子吃饭了");
    }
}

 

        

        <3>但是儿子太小,需要有人辅助,才能吃饭.这里采用了动态技术,不再硬性指定妈妈做为代理对象了.

           这个对象由程序自动生成.

        

 

1
2
3
4
5
6
7
8
9
10
      11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class Main {
 
    public static void main(String[] args) {
        //儿子没有学会吃饭,需要找一个代理,不再手工去生成一个代理对象(妈妈)了
        final Father son=new Son();//目标对象
        //使用jdk的Proxy动态生成一个代理(妈妈)
         
         
        Father tagert= (Father) Proxy.newProxyInstance(Son.class.getClassLoader(), Son.class.getInterfaces(), new InvocationHandler() {
            /**
             * Proxy,运行时生成的代理对象
             * method,委托类的方法
             * agrs,委托类的方法参数
             */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                System.out.println("动态生成的代理对象的class:"+proxy.getClass());
                System.out.println("目标对象的方法:"+method.getName());
                System.out.println("目标对象的参数:"+Arrays.toString(args));
                 
                System.out.println("代理对象(妈妈)给儿子喂饭");
                Object object = method.invoke(son, args);
                System.out.println("代理对象(妈妈)给儿子擦嘴");
                return object;
            }
        });
         
        tagert.eat();
    }
}

 

        <4>结果:

         

 

 

        JDK的动态代理只能针对有接口的委托类.

 

    (2)CGLB动态代理,实现类实现的动态代理.

        CGLB包底层是通过小而快的字节码处理框架ASM(JAVA字节码操控框架)来转换字节码生成新的类.

        其代理类是委托类的子类.

 

        <1>继续上述例子.因为CGLB是对类实现的动态代理,所以该类是没有接口的.

1
      2
3
 4
5
6
public class Son {
 
    public void eat() {
        System.out.println("儿子吃饭了");
    }
}

 

        

        <2>因为儿子太小,需要给其找个代理辅助.但是Son没有接口,采用CGLB来根据Son来动态创建Son的子类(代理类).

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class Main {
 
    public static void main(String[] args) {
        final Son son=new Son();
         
        //类似JDK的Proxy,用它来创建动态代理类(子类)
        Enhancer enhancer=new Enhancer();
         
        //设置委托类(父类),类似Proxy传入接口
        enhancer.setSuperclass(Son.class);
         
        //设置事件处理程序,类似InvocationHandler
        enhancer.setCallback(new MethodInterceptor() {
             
            /**
             * proxy:运行时的代理类对象
             * method:目标对象的方法
             * args:目标对象方法的参数
             * methodProxy:代理类方法
             */
            @Override
            public Object intercept(Object proxy, Method method, Object[] args,
                    MethodProxy methodProxy) throws Throwable {
                System.out.println("运行时动态生成的代理类:"+proxy.getClass());
                System.out.println("目标对象的方法:"+method.getName());
                System.out.println("目标对象的方法参数:"+Arrays.toString(args));
                System.out.println("代理对象的方法:"+methodProxy);
                System.out.println("CGLB动态生成的代理类(妈妈/保姆)给儿子喂饭");
                Object object = method.invoke(son, args);
                System.out.println("CGLB动态生成的代理类(妈妈/保姆)给儿子擦嘴");
                return object;
            }
        });
         
        //根据前面的配置动态生成代理类(son的子类)
        Son sonProxy = (Son) enhancer.create();
        sonProxy.eat();
    }
}

 

 

    ​    ​<2>结果:

    ​    ​

 

​    ​    ​CGLB重写父类(委托类)的非final方法,非final类,非static和非private方法.

 

 

 

 

 

 

 

 

 

        

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 大小: 26.3 KB
  • 大小: 6.6 KB
  • 大小: 23.1 KB
分享到:
评论

相关推荐

    代理模式的使用示例程序

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原始对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者在不修改原有对象的情况下,增强或扩展其...

    JAVA设计模式之代理模式实例

    代理模式是设计模式的一种,它提供了一种对目标对象进行增强或者控制访问的方式。在本实例中,我们将深入探讨Java中的代理模式及其应用。 代理模式的核心思想是为一个对象创建一个代理对象,这个代理对象在客户端和...

    设计模式之代理模式Proxy

    代理模式是设计模式中的一种结构型模式,它在对象交互中起到了中介的作用,允许通过代理对象来控制对原对象的访问。代理模式的核心思想是为一个对象提供一个替身,以便增加新的功能或者控制对原对象的访问。这种模式...

    设计模式-代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要的角色,特别是在iOS平台的应用程序设计中。代理模式的核心思想是为一个对象提供一个替身或代理,以控制对这个对象的访问。这种模式允许我们通过代理来间接...

    java中的三种代理模式

    在Java编程中,代理模式是一种常用的面向对象设计模式,它允许我们为一个对象提供一个代理以控制对该对象的访问。代理模式通常用于增加额外的功能,如日志、权限检查等,或者为了创建虚拟代理以提高性能。以下是Java...

    JAVA设计模式(代理模式)

    **Java设计模式——代理模式详解** 代理模式是软件设计模式中的一个重要组成部分,它在Java编程中扮演着举足轻重的角色。代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象可以控制对原...

    代理模式小例子

    代理模式是一种设计模式,它在软件工程中扮演着重要的角色,允许我们为其他对象提供一个替代接口,以控制对原对象的访问。这种模式的主要目的是为了增加灵活性、安全性或者为对象提供额外的功能,同时保持客户端代码...

    设计模式之代理模式proxy

    **设计模式之代理模式(Proxy Pattern)** 设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的模板。代理模式是其中一种行为设计模式,它的核心思想是为一个对象提供一个替身或者代理,以控制对...

    设计模式实现——代理模式

    **设计模式实现——代理模式** 在软件工程中,设计模式是一种通用可重用的解决方案,它描述了在特定上下文中经常出现的问题以及该问题的解决方案。代理模式是设计模式的一种,它提供了一种对目标对象的间接访问方式...

    结构型模式之代理模式(Proxy)

    代理模式是一种设计模式,属于结构型模式之一,其主要目的是为其他对象提供一个代理,以控制对该对象的访问。在实际应用中,代理模式能够帮助我们实现如下的功能: 1. 远程代理:代理对象可以代表一个位于远程系统...

    Java设计模式-代理模式例子

    在这个“Java设计模式-代理模式例子”中,我们将深入探讨代理模式的概念、实现方式以及它在实际开发中的应用。 代理模式的核心思想是为一个对象提供一个替身,这个替身即代理对象,代理对象控制对原对象的访问。在...

    android设计模式之代理模式

    代理模式在软件设计中是一种常用的设计模式,尤其在Android开发中,它可以帮助我们实现复杂的控制逻辑,隔离复杂性,以及提供额外的功能。在Android上下文中,代理模式常常用于数据加载、权限控制、事件处理等方面。...

    设计模式C++学习之代理模式(Proxy)

    代理模式是一种设计模式,它是结构型模式之一,主要用于在客户端和目标对象之间建立一个代理对象,以便控制对目标对象的访问。在C++中,代理模式可以用来为其他对象提供一种代理以控制对这个对象的访问,或者增加...

    Java代理模式Java动态代理

    ### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...

    设计模式--代理模式

    代理模式是一种常用的设计模式,它在软件开发中扮演着重要角色,允许我们通过一个代理类来控制对原对象的访问。在《设计模式:可复用面向对象软件的基础》(通常称为GoF设计模式)中,代理模式被定义为“为其他对象...

    代理模式 C++实现

    代理模式(Proxy) 定义: 为其他对象提供一种代理以控制对这个对象的访问 结构: 由三部分组成 1.RealSubject(真实对象): 真正会调用到的对象 2.Proxy(代理对象): 代理真实对象的地方 3.Subject(共同点): 代理对象...

    cas代理模式代码示例

    在IT行业中,代理模式是一种常见的设计模式,它允许我们在不修改原有对象的基础上,为对象添加新的功能或控制访问。在本示例中,我们将重点讨论如何在Java环境下使用代理模式来实现代理逻辑,特别是在CAS(Central ...

    C#设计模式—代理模式应用实例

    代理模式是其中一种,它在软件设计中扮演着重要角色。本实例将详细阐述如何在C#中运用代理模式。 代理模式的主要思想是为一个对象提供一个替身或代理,以便控制对这个对象的访问。代理对象在客户端和目标对象之间起...

    .net实现设计模式之代理模式

    代理模式是一种常用的设计模式,它在软件工程中扮演着重要的角色,特别是在.NET框架下。代理模式的核心思想是为一个对象提供一个替代品或代表,这个替代品能够控制对原对象的访问,使得客户端代码可以通过代理对象与...

Global site tag (gtag.js) - Google Analytics