`

JDK动态代理实现原理

阅读更多
   昨天下午终于签好了合同。今天下午午觉醒来,便开始了JDK动态代理模拟原理的学习和研究。
   首先,我们应该明白何为代理,所谓代理,按照我的理解,用户只需要知道接口中的方法名,不需要了解方法中的具体实现,就可以进行远程访问。
   在应用上可以用在考试系统中,一个服务器,多个考试机调用服务器上面的方法,以及其他的一些web应用。同时,很多开源框架上也用到了反射,如spring对封装的数据库事务控制,对业务bean的创建。
   再者,对于代理,分为两种,一种是静态代理,一种为动态代理。无论静态代理还是动态代理,一下几个模块:1.接口类 2. 真实实现类 3. 代理类(动态代理和静态代理有区别) 4. 代理工厂类。 对于静态代理,代理类中要有接口类中全部方法的实现,这样一来,如果项目后期工程中在接口中增加方法时,则在代理中同样要对该方法进行增加调用,这样一来维护起来麻烦,对于动态代理,则不存在此问题,因为在动态代理的类中,只需要实现InvocationHandler中的invoke方法即可,该方法可以调用接口中的所有方法。
   动态代理的实现主要还是借助JDK中的反射机制,主要使用到了java.lang.reflect包中的InvocationHandler接口、Proxy类,java.lang.ClassLoader类。
   InvocationHandler接口是代理程序实现逻辑的接口,Proxy创建动态代理类使用。
   Proxy类,提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类 ,这里主要用到了newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,需要说明下ClassLoader指的是代理类的处理机(InvocationHander)的ClassLoader,接口指的是实际对象实现的接口,InvocationHander就是InvocationHander,至于其他的静态方法,你可以自己查API(备注:我用的JDK是1.6),生成的代理类就声称实现了对应的接口并实现了对应的方法。
   ClassLoader类:负责加载类的对象,数组类(Array)除外。
下面开始进行动态代理的springAOP控制原理的演示:
   首先进行结构说明:
        1.接口(必须要有,JDK创建代理对象需要用到)
        2.接口实现类
        3.代理类(AOP,事务控制,日志记录等)
        4.代理工厂
        5.测试类
1.接口:
Subject(此处是参考iteye别处的代码,不是原创)
/**
* 顶层接口
*
* @author iteye 2013-07-13
*/
public interface Subject {
/**
* 执行任务1
* @param taskName1 任务名
*/
public abstract void doTask1(String taskName1);

/**
* 执行任务2
* @param taskName2 任务名
*/
public abstract void doTask2(String taskName2);

/**
* 执行任务3
* @param taskName3 任务名
*/
public abstract void doTask3(String taskName3);
}
2.接口实现类

/**
* 动态代理实现类
*
* @author XiaoYun 2013-07-13
*/
public class RealSubject implements Subject {

@Override
public void doTask1(String taskName1) {
System.out.println(taskName1 + "开始执行!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskName1 + "执行完毕!");
}

@Override
public void doTask2(String taskName2) {
System.out.println(taskName2 + "开始执行!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskName2 + "执行完毕!");
}

@Override
public void doTask3(String taskName3) {
System.out.println(taskName3 + "开始执行!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(taskName3 + "执行完毕!");
}

}
3.动态代理类
/**
* 代理实例的调用处理程序
*
* @author XiaoYun 2013-07-13
*/
public class ProxySubject implements InvocationHandler{

private Object delegate;

public ProxySubject(Object delegate) {
this.delegate = delegate;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
                  //此处可以进行日志记录或者事务操作
                     //Spring的AOP原理就是如此
method.invoke(delegate, args);
                  //此处可以进事务处理操作(数据库回滚可以放到异常中进行)
System.out.println(args[0] + "已执行!");
return null;
}

}
  说明:如果为静态代理类:则invoke方法需要去掉,然后根据接口中的方法加上对应的方法,并在该方法中加上方法调用。说到这里可能可能大家也都晕了,还是把代码写出来吧,对应的应该是这样子:

/**
* 静态代理类,要实现接口类(此处参考了iteye的部分代码)
* @author iteye 2013-07-13
*/
public class ProxySubject implements Subject {

private Subject delegate;

public ProxySubject(Subject delegate) {
this.delegate = delegate;
}
/**
* 代理方法
*/
@Override
public void doTask1(String taskName) {
this.delegate.doTask(taskName);
}
         @Override
public void doTask2(String taskName) {
this.delegate.doTask(taskName);
}
         @Override
public void doTask2(String taskName) {
this.delegate.doTask(taskName);
}


}
4.代理工厂类

/**
* 代理工厂
*
* @author XiaoYun 2013-07-13
*/
public class SubjectDynamicProxyFactory {

public static Subject getSubject() {
Subject proxy = null;
//得到实际逻辑实现类
Subject delegate = new RealSubject();
//得到代理类
InvocationHandler hander = new ProxySubject(delegate);
//根据该实现类的类加载器,代理类接口,代理类实际程序接口得到代理对象
proxy = (Subject)Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), hander);
return proxy;
}
}
5.测试类
/**
* 动态代理测试
*
* @author XiaoYun 2013-07-13
*/
public class Client {
public static void main(String[] args) {
Subject delegate = SubjectDynamicProxyFactory.getSubject();
delegate.doTask1("任务一");
delegate.doTask2("任务二");
delegate.doTask3("任务三");
}
}
    关于运行结果,希望大家自己先想一下应该是一个什么结果,然后再运行。其实我也想引用马士兵老师的一句话,学习的规律是先学习使用用,然后去了解底层实现,当然我认为其实能先理解原理更好,如果理解不了也没关系,写多了,自己多做总结,多思考,自然而然的就能领悟到其中的原理了,反正这是我的心得,希望对一些初学者有帮助,我也是刚用java大概有一年时间。
    代码至此告一段落,动态代理原理即时如此。当然我学习到的可能也不完整,毕竟只花了半个下午的时间来做这件事儿。
     项目中用到的代理可以节约很多时间和多余的工作,所以学习下还是不错的。在这之前,我也经常在iteye上浏览别人的博客,一直都知道动态代理应该算是java中比较高级的部分了,终于我自己也在iteye上发了一篇,都是自己的心得。大家有什么疑问和建议欢迎给我留言,大家一起进步,学习的不足的地方还请前辈们不吝赐教。肖云  
分享到:
评论

相关推荐

    Java JDK动态代理实现原理实例解析

    Java JDK动态代理实现原理实例解析 Java JDK动态代理实现原理实例解析是指通过Java JDK提供的代理机制来实现动态代理的原理和实例解析。动态代理是一种非常重要的设计模式,它可以在运行时生成代理类,从而实现了...

    JDK动态代理_JDK动态代理

    本文将详细介绍JDK动态代理的原理与应用,帮助读者深入理解其工作方式以及如何在实际项目中运用。 #### 二、JDK动态代理简介 JDK动态代理是Java平台提供的一个工具包,用于在运行时创建代理对象。它主要适用于实现...

    JDK动态代理 spring aop 的原理

    现在让我们深入探讨JDK动态代理和Spring AOP的原理。 首先,JDK动态代理基于Java的反射机制,通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,...

    关于jdk动态代理的源码剖析

    - **只能代理实现了接口的类**:这是JDK动态代理的一个限制,如果目标对象没有实现任何接口,则无法使用JDK动态代理。 - **性能开销**:虽然这种开销通常很小,但在高并发场景下可能会成为瓶颈。 通过上述分析,...

    JDK动态代理源码

    在Java编程领域,JDK动态代理是一个非常重要的概念,它允许我们在...理解并掌握JDK动态代理的原理和用法,能够帮助我们更灵活地设计和实现程序,特别是在需要扩展或增强已有功能时,动态代理提供了一种优雅的解决方案。

    Spring Aop的底层实现技术 --- Jdk动态代理原理

    Spring AOP 的底层实现技术 --- Jdk 动态代理原理 JDK 动态代理是 Spring AOP 的底层实现技术,允许开发者在运行期创建接口的代理实例。在 JDK 1.3 以后,JDK 动态代理技术提供了实现 AOP 的绝好底层技术。JDK 动态...

    JDK动态代理简单示例

    除了基本的代理实现,JDK动态代理还可以结合其他设计模式,如工厂模式,创建更加复杂的代理对象。此外,Spring框架中的AOP功能也是基于JDK动态代理或CGLIB实现的,它允许开发者定义切面,对满足特定条件的方法进行...

    模拟JDK动态代理内部实现

    在本文中,我们将深入探讨如何模拟JDK的动态代理内部实现。 首先,我们需要了解JDK动态代理的基础知识。Java中的动态代理通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。`Proxy...

    Jdk动态代理和cglib动态代理原理

    - **JDK代理**适用于目标类实现有接口的情况,更符合面向接口的设计原则,且无需引入额外的库。 - **CGLIB代理**适用于目标类没有接口或者不希望修改原有接口的情况,其性能通常优于JDK代理,因为它是基于字节码生成...

    JDK动态代理的底层实现原理

    JDK动态代理的底层实现原理

    jdk与cglib动态代理与底层实现

    4. **底层实现原理**: - **JDK代理**:JDK动态代理使用反射和InvocationHandler接口生成一个实现了目标接口的新类。在运行时,这个新类的实例作为代理对象,它的方法调用都会转发到InvocationHandler的`invoke()`...

    java-jdk动态代理的实现demo

    Java JDK 动态代理是一种强大的特性,它允许我们在运行时创建代理类,这些代理类可以扩展或修饰已存在的接口实现。动态代理在很多场景下非常有用,比如日志记录、性能监控、事务管理等,这些功能可以在不修改原始...

    CGLIB 和 JDK生成动态代理类的区别

    CGLIB和JDK动态代理是两种常用的实现方式,它们各有优缺点,适用于不同的场景。下面将详细探讨这两种动态代理的区别。 首先,JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect....

    JDK动态代理proxy

    下面将详细介绍JDK动态代理的工作原理及其实现方式。 ### 1. 动态代理概述 在Java中,动态代理主要由两个类完成:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。`Proxy` 类用于创建一个...

    JDK动态代理在EJB3(包括WebService)中的应用

    首先,我们来理解JDK动态代理的工作原理。在Java中,动态代理通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象,该对象可以作为一个接口的实例,而...

    JavaEE JDK动态代理实现AOP切面功能

    一、JDK动态代理的基本原理 1. `Proxy`类:这个类是Java动态代理的入口,它提供了一种创建代理对象的方式。通过`Proxy.newProxyInstance()`方法,我们可以根据一个接口生成一个实现了该接口的代理对象。 2. `...

    JDK动态代理和Cglib动态代理实例源码

    1. **JDK动态代理实现过程**: - 定义一个接口,被代理类实现该接口。 - 创建`InvocationHandler`实现类,重写`invoke`方法,此方法会在调用被代理类的任何方法时被调用。 - 使用`Proxy.newProxyInstance()`创建...

    模拟JDK动态代理

    在Java编程中,JDK动态代理是一种非常重要的技术,它允许我们在运行时创建对现有接口的代理实现。这种技术在很多场景下都有广泛的应用,比如AOP(面向切面编程)、事务管理、缓存处理等。现在我们来深入探讨一下JDK...

Global site tag (gtag.js) - Google Analytics