黑马程序员-动态代理

来源:互联网 发布:魔兽世界7.0数据库 编辑:程序博客网 时间:2024/06/06 02:43

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

    JAVA的动态代理 


    代理模式
    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 
    按照代理的创建时期,代理类可以分为两种。 
    静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了,所以静态代理是使用硬编码的方式实现的,这在开发中并不适用。
    动态代理:在程序运行时,运用反射机制动态创建而成。 通俗点讲就是在运行时由配置文件决定要运行哪个类。

    可以i加系统功能的位置:
         1.在调用目标方法之前
         2.在调用目标方法之后
         3.在调用目标方法前后
         4.在处理目标方法异常的catch块中

    说先说一下静态代理:

package com.itheima;//代理类和目标类的公共接口interface MyInter {    public void method();}// 委托类class Target implements MyInter {    public void method() {        System.out.println("Target...method");    }}// 静态代理类实现和委托类同样的接口class ProxyBsc implements MyInter {    // 接口的对象    private MyInter b;    //将为委托类作为参数传递进来    public ProxyBsc(MyInter b) {        this.b = b;    }    public void method() {                //在这里可以写要增加的功能。        //System.out.println("Target...method");       //在这里也能写要增加的功能。    }}// 生成静态代理工厂,客户并不知道返回的是代理类对象还是委托类对象class MyInterStaicFactory {    public static MyInter getInstance() {        // 返回代理类对象        return new ProxyBsc(new Target());    }}// 客户类public class Client {    public static void main(String[] args) {        MyInter MyInter = MyInterStaicFactory.getInstance();        MyInter.method();    }}


    下面来看动态代理:

package com.itheima;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import java.util.ArrayList;import java.util.Collection;public class ProxyDemo {    public static void main(String[] args) throws Exception {        // 指定一个接口的类加载器和字节码获得代理类的字节码        Class clazzProxy = Proxy.getProxyClass(                Collection.class.getClassLoader(), Collection.class);        // 获得全部的构造方法        Constructor cons[] = clazzProxy.getConstructors();        // 查看全部的构造方法,从查看的结果得知有$Proxy0(InvocationHandler)的构造方法        for (Constructor clazzCons : cons) {            System.out.println(clazzCons);        }        Constructor con = clazzProxy.getConstructor(InvocationHandler.class);        // 实现了匿名内部类InvocationHandler        Collection proxy = (Collection) con                .newInstance(new InvocationHandler() {                    // 代理要实现的类,即目标类                    ArrayList array = new ArrayList();                    @Override                    public Object invoke(Object arg0, Method arg1, Object[] arg2)                            throws Throwable {                        // 记录开始时间                        long startTime = System.currentTimeMillis();                        // 传入参数并反射调用ArrayList的方法                        Object obj = arg1.invoke(array, arg2);                        // 记录方法结束时间                        long endTime = System.currentTimeMillis();                        // 调用方法耗时                        System.out.println();                        return null;                    }                });        // 输出"null",因为可以调用toString()所以不是真正意义上的null.        System.out.println(proxy.toString());        proxy.add("你好");        proxy.add("中国");        System.out.println(proxy);        // 输出集合长度        System.out.println(proxy.size());        // clear()方法无返回值可以调用        proxy.clear();    }}







0 0
原创粉丝点击