java 动态代理

来源:互联网 发布:幻刃网络 编辑:程序博客网 时间:2024/05/17 04:58

在代理模式中主要有这样几个角色:

1、什么是代理模式

2、什么是动态代理模式

3、使用静态/动态代理模式有什么好处

4、动态代理一般在哪里使用

个人理解:代理模式就是当你要访问一个类的方法时,不能直接访问,要通过一个类,通过这个类才能访问到你要访问的类,在大话设计模式中举了一个例子:

你要找局长办事,但你直接找不到,这时你要通过秘书来办理你要办的事,而最后具体的事情还是由局长来办理,其中秘书就是一个代理类,局长就是被代理类,局长秘书这个关系就把局长秘书关联起来了

引用:代理模式是常用的Java 设计模式,它的特征是代理类与委托类(被代理类)有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类(被代理类),以及事后处理消息等。代理类与委托类(被代理类)之间通常会存在关联关系,一个代理类的对象与一个委托类(被代理类)的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类(被代理类)的对象的相关方法,来提供特定的服务。按照代理类的创建时期,代理类可分为两种。静态代理类:     由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:    在程序运行时,运用反射机制动态创建而成。
好处:
   人家是动态编程,需要在原来的方法的功能基础上再添加一些功能,而不用改变这个方法的签名,原来调用这个方法的类依然能正常工作。比如,现在要把一段文本发送给另一个人,普通方法是 void send(File a),现在我们弄出个特性,就像 Spring AOP 那样,在 send 之前给这个 a 压缩一下。原来的程序没有压缩功能,现在我们需要添加的话而不改变原来所有的代码的话就得用类似 AOP 这样的代码来处理。一般一个无法再继承的类和方法,要用代理,而能够继承的类和方法可以在内在中直接生成一个新的 java 类继承它然后覆盖掉那个 send 方法,像 hibernate/spring/jboss 都把这些自动完成了。而像 AspectJ 这种 AOP 则不同,它直接把人家的 class 代码修改了,它就不需要使用代理。

1、 抽象角色(接口,动态代理中只能是接口)、真实角色、代理角色,其中真实角色和代理角色有相同的方法,代理角色所代表的真实对象,是我们最终要引用的对象。

2、使用到的类以及接口:Proxy  生成代理者 ,InvocationHandler 调用处理器 生成的代理者调用方法其实就是去执行这个接口的invoke方法,而invoke方法中我们在调用委托类的具体方法在执行这个方法之前我们可以进行相关的处理,执行后也可以作相应的处理,在动态代理中InvocationHandler调用处理器 作用很大,将代理类和被代理类(真实类)关联起来

** 学习的时候看到这个图,个人感觉这个图形对动态代理说的很明白  **


具体实例:

package com.reflect;

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;

/**
 * @author WHD 2014-10-12
 */

// 客户端测试
public class ProxyFor {
    public static void main(String[] args) throws NoSuchMethodException,
            SecurityException, InstantiationException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException {
        // 真实类
        Person4imp p4 = new Person4imp();
        // 调用处理程序和真实类关联起来
        MyInvocationHandler4 myi4 = new MyInvocationHandler4(p4);
        // 代理类的创建
        Class<?> clas = Proxy.getProxyClass(Person4.class.getClassLoader(),
                Person4.class);
        Constructor con = clas.getConstructor(InvocationHandler.class);
        // 代理类实例,可以把他理解为Person4 这个接口的“实现类”,其实不是,
        // 而传递调用处理程序的实例是因为代理类对象调用方法时其实就是执行InvocationHandler接口的invoke方法
        Person4 per = (Person4) con.newInstance(myi4);
        per.ask("moning1");
        per.say(10);
    }
}

interface Person4 {
    void say(int age);
    void ask(String name);
}

// 真实类(被代理类)
class Person4imp implements Person4 {
    @Override
    public void ask(String name) {
        // TODO Auto-generated method stub
        System.out.println("name" + name);
    }

    @Override
    public void say(int age) {
        System.out.println("age" + age);
        // TODO Auto-generated method stub
    }

}

// 调用处理器接口实现
class MyInvocationHandler4 implements InvocationHandler {
    // 作用就是将代理者和真实者关联起来
    private Object person;
    public MyInvocationHandler4() {
    };

    public MyInvocationHandler4(Object obj) {
        this.person = obj;
    }

    @Override
    // 代理者执行的时候是执行 invoke方法,而invoke方法中使用反射去执行真实类(被代理类)的方法
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        // 执行真实者的方法
        Object result = method.invoke(person, args);
        // result 为真实者相应的方法的返回值。
        return null;
    }
}



0 0
原创粉丝点击