黑马程序员-动态代理

------<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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值