JAVA设计模式之【代理模式】二(jdk动态代理)

接上篇JAVA设计模式之【代理模式】二(静态代理)http://blog.csdn.net/emma_joans/article/details/78564585

动态代理

上述代理方式为静态代理,下面讲述两种动态代理方式:

  • jdk动态代理: 面向接口
  • cglib动态代理:面向无接口

jdk动态代理

java动态代理类位于java.lang.reflect.Proxy包下,创建代理类对象的方式是:
1. 创建被代理的类以及接口
2. 创建一个实现接口InvocationHandler的类,也就是处理器对象,它必须实现invoke方法
3. 通过Proxy的静态方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)创建一个代理对象
4. 通过代理对象调用方法

创建处理器对象类源码参数说明:

实现InvocationHandler类,重写invoke方法
/**
    invoke方法参数说明
*  public Object invoke(Object obj, Object... args)
*  反射机制
*  obj      被代理的对象(实际的对象)
*  args method方法的参数
*/

创建代理对象源码及参数说明:

public static Object newProxyInstance(ClassLoader loader,
          Class<?>[] interfaces, InvocationHandler h)
        throws IllegalArgumentException
    {
        ....
    }

参数说明:

/*
     * static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
     * 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。 
     *  参数:
     *      ClassLoader loader:传递类加载器,加载类到内存中,创建class文件对象;可以传递本类的类加载器
     *      Class<?>[] interfaces:传递ArrayList实现的接口List/Collection的Class文件对象
     *      InvocationHandler h:创建一个InvocationHandler的实现类,重写接口中的方法invoke,对集合的方法进行判断
     *       如果调用add方法,没有对集合进行修改,则允许执行
     * 返回值类型:
     *      Object:返回被代理后的方法返回值
    */  

一个小栗子说明动态代理的实现过程:

  1. 首先我们要定义一个接口:
/**
 * 接口
 * @author wuqiong
 *
 */
public interface IStudent {

    public void study();

    public int totalCourse(String name);

}

定义一个实现类,实现这个接口:

/**
 * 实现接口,重写方法
 * @author wuqiong
 *
 */
public class StudentImpl implements IStudent {

    public void study() {
        System.out.println("学生学习...");
    }

    public int totalCourse(String name) {
        return 9;
    }

}

利用java反射机制,创建处理器对象。真实对象需要实现InvocationHandler接口,重写invoke()方法。

处理器对象如下:

/**
 * 处理器对象,反射机制
 * @author wuqiong
 *
 */
public class JDKDynamicInvocation implements InvocationHandler{

    private Object target;

    public JDKDynamicInvocation(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        // 增强方法在真正方法执行之前执行
        before();


        Object result = method.invoke(target, args);

        // 增强方法在真正方法执行之前执行
        after();

        return result;
    }

    /**
     * 增强方法
     */
    public void before() {
        System.out.println("起床去上学...");
    }

    /**
     * 增强方法
     */
    public void after() {
        System.out.println("骑自行车放学");
    }

}

下面是对代理类对象的测试:

/**
 * 动态代理类方法测试
 * @author wuqiong
 *
 */
public class JDKProxyTest{

    public static void main(String[] args) {

    // 创建真实对象
    IStudent student = new StudentImpl();

    // 创建处理器对象,将真实对象作为参数传给处理器对象
    JDKDynamicInvocation jdkDynamicProxcy = new JDKDynamicInvocation(student);

    // 创建代理类对象
            IStudent studentProxy = (IStudent) Proxy.newProxyInstance(student.getClass().getClassLoader(),
    student.getClass().getInterfaces(), jdkDynamicProxcy);

    // 执行代理了对象的study()方法
    studentProxy.study();

    }

}

打印结果如下:

起床去上学...
学生学习...
骑自行车放学

我们可以看到,在执行study()方法之前执行了before()方法,打印“起床去上学…”,执行study()方法之后执行了after()方法,打印“骑自行车放学”。

老大让我干活了。下次继续。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值