精华内容
下载资源
问答
  • java 反射与动态代理

    2011-08-03 13:59:04
    java 反射与动态代理 源代码,java文件。
  • Java反射与动态代理

    2016-10-04 11:28:25
    Java反射机制与动态代理
  • java反射与动态代理

    千次阅读 2014-09-27 23:24:11
    一直分不清的两个东西,今天记录一下,java反射与动态代理 java反射:1、在运行时分析类的能力  2、在运行是查看对象  3、实现数组的操作代码  4、利用Method对象  在java.lang.reflect包中有三个类Field、...

    一直分不清的两个东西,今天记录一下,java反射与动态代理

    java反射:1、在运行时分析类的能力

         2、在运行是查看对象

       3、实现数组的操作代码

       4、利用Method对象

     在java.lang.reflect包中有三个类Field、Method、Constructor分别用于描述类的域、方法和构造器,这三个类都有一个叫做getName的方法,用来返回相应的名称。

    Field类有一个getType方法,用于返回描述域所数类型的Class类型对象。Method和Contructor类包含有能够报告参数类型的方法,Method类型还可以报告返回类型

    这是三个类还有一个叫做getModifiers的方法,它将返回一个整型数值,用不同的位开关设置描述public和static这些修饰的使用状况。

    另外,还可以利用java.lang.reflect包中的Modifier类的静态方法分析getModifiers返回的整型数值。例如Modifire.isPublic,isPrivate,isFinal等等

    class类中的getFields,getMethods和getConstructors方法将分别返回类支持的public域,方法和构造器数组,其中包括超类的共有成员。Class类的getDeclareFields

    getDeclareMethods和getDeclaredConstructors方法分别返回类中声明的全部与,方法和构造器数组,其中包括私有和受保护的成员,但不包括超类的成员,以下java代码是用了反射的一小段代码

    	Class<Test> c=Test.class;
    		Test t=c.newInstance();
    		t.setId(1);
    		Field f=c.getDeclaredField("id");
    		f.setAccessible(true);
    		System.out.println(f.get(t));
    		f.setAccessible(false);
    		Method m=c.getMethod("getId");
    		Object o=m.invoke(t);
    		System.out.print(o);

    动态代理:代理模式 ,这是一种设计模式 而java反射是java语言分析类结构,动态执行java程序的本身具有的一种能力,和模式没关系
    代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。 

    当然两者结合起来可以干很多事,比如面向aop编程,Spring的aop就是这么干的,这里不多说,并且很多框架都用了反射,在执行某个方法,获取参数时就会用到,反射是获取不到方法执行的参数的

    资料引用:java核心技术第一版

    转载之后请注明出处:http://blog.csdn.net/xh199110/article/details/39620473    飞天博客

    谢谢


    展开全文
  • java反射与动态代理
  • http://www.infoq.com/cn/articles/cf-java-reflection-dynamic-proxy Java 反射与动态代理
    展开全文
  • Java动态代理的底层是通过反射机制来实现的,反射是基础,动态代理Proxy类中有有相关反射代码。

    Java动态代理的底层是通过反射机制来实现的,反射是基础,动态代理Proxy类中有有相关反射代码。

    展开全文
  • 在上一篇文章中介绍Java注解的时候,多次提到了Java反射API。javax.lang.model不同的是,通过反射API...反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能。正如英文单词reflectio

    上一篇文章中介绍Java注解的时候,多次提到了Java的反射API。与javax.lang.model不同的是,通过反射API可以获取程序在运行时刻的内部结构。反射API中提供的动态代理也是非常强大的功能,可以原生实现AOP中 的方法拦截功能。正如英文单词reflection的含义一样,使用反射API的时候就好像在看一个Java类在水中的倒影一样。知道了Java类的内部 结构之后,就可以与它进行交互,包括创建新的对象和调用对象中的方法等。这种交互方式与直接在源代码中使用的效果是相同的,但是又额外提供了运行时刻的灵活性。使用反射的一个最大的弊端是性能比较差。相同的操作,用反射API所需的时间大概比直接的使用要慢一两个数量级。不过现在的JVM实现中,反射操作的性能已经有了很大的提升。在灵活性与性能之间,总是需要进行权衡的。应用可以在适当的时机来使用反射API。

    基本用法

    Java 反射API的第一个主要作用是获取程序在运行时刻的内部结构。这对于程序的检查工具和调试器来说,是非常实用的功能。只需要短短的十几行代码,就可以遍历出来一个Java类的内部结构,包括其中的构造方法、声明的域和定义的方法等。这不得不说是一个很强大的能力。只要有了java.lang.Class类 的对象,就可以通过其中的方法来获取到该类中的构造方法、域和方法。对应的方法分别是getConstructorgetFieldgetMethod。这三个方法还有相应的getDeclaredXXX版本,区别在于getDeclaredXXX版本的方法只会获取该类自身所声明的元素,而不会考虑继承下来的。ConstructorFieldMethod这三个类分别表示类中的构造方法、域和方法。这些类中的方法可以获取到所对应结构的元数据。

    反射API的另外一个作用是在运行时刻对一个Java对象进行操作。 这些操作包括动态创建一个Java类的对象,获取某个域的值以及调用某个方法。在Java源代码中编写的对类和对象的操作,都可以在运行时刻通过反射API来实现。考虑下面一个简单的Java类。

    class MyClass {
        public int count;
        public MyClass(int start) {
            count = start;
        }
        public void increase(int step) {
            count = count + step;
        }
    } 


    使用一般做法和反射API都非常简单。

    MyClass myClass = new MyClass(0); //一般做法
    myClass.increase(2);
    System.out.println("Normal -> " + myClass.count);
    try {
        Constructor constructor = MyClass.class.getConstructor(int.class); //获取构造方法
        MyClass myClassReflect = constructor.newInstance(10); //创建对象
        Method method = MyClass.class.getMethod("increase", int.class);  //获取方法
        method.invoke(myClassReflect, 5); //调用方法
        Field field = MyClass.class.getField("count"); //获取域
        System.out.println("Reflect -> " + field.getInt(myClassReflect)); //获取域的值
    } catch (Exception e) { 
        e.printStackTrace();
    } 


    由于数组的特殊性,Array类提供了一系列的静态方法用来创建数组和对数组中的元素进行访问和操作。

    Object array = Array.newInstance(String.class, 10); //等价于 new String[10]
    Array.set(array, 0, "Hello");  //等价于array[0] = "Hello"
    Array.set(array, 1, "World");  //等价于array[1] = "World"
    System.out.println(Array.get(array, 0));  //等价于array[0]

    使用Java反射API的时候可以绕过Java默认的访问控制检查,比如可以直接获取到对象的私有域的值或是调用私有方法。只需要在获取到Constructor、Field和Method类的对象之后,调用setAccessible方法并设为true即可。有了这种机制,就可以很方便的在运行时刻获取到程序的内部状态。

    处理泛型

    Java 5中引入了泛型的概念之后,Java反射API也做了相应的修改,以提供对泛型的支持。由于类型擦除机制的存在,泛型类中的类型参数等信息,在运行时刻是不存在的。JVM看到的都是原始类型。对此,Java 5对Java类文件的格式做了修订,添加了Signature属性,用来包含不在JVM类型系统中的类型信息。比如以java.util.List接口为例,在其类文件中的Signature属性的声明是<E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;; ,这就说明List接口有一个类型参数E。在运行时刻,JVM会读取Signature属性的内容并提供给反射API来使用。

    比如在代码中声明了一个域是List<String>类型的,虽然在运行时刻其类型会变成原始类型List,但是仍然可以通过反射来获取到所用的实际的类型参数。

    Field field = Pair.class.getDeclaredField("myList"); //myList的类型是List 
    Type type = field.getGenericType(); 
    if (type instanceof ParameterizedType) {     
        ParameterizedType paramType = (ParameterizedType) type;     
        Type[] actualTypes = paramType.getActualTypeArguments();     
        for (Type aType : actualTypes) {         
            if (aType instanceof Class) {         
                Class clz = (Class) aType;             
                System.out.println(clz.getName()); //输出java.lang.String         
            }     
        } 
    }  


    动态代理

    熟悉设计模式的人对于代理模式可 能都不陌生。 代理对象和被代理对象一般实现相同的接口,调用者与代理对象进行交互。代理的存在对于调用者来说是透明的,调用者看到的只是接口。代理对象则可以封装一些内部的处理逻辑,如访问控制、远程通信、日志、缓存等。比如一个对象访问代理就可以在普通的访问机制之上添加缓存的支持。这种模式在RMIEJB中都得到了广泛的使用。传统的代理模式的实现,需要在源代码中添加一些附加的类。这些类一般是手写或是通过工具来自动生成。JDK 5引入的动态代理机制,允许开发人员在运行时刻动态的创建出代理类及其对象。在运行时刻,可以动态创建出一个实现了多个接口的代理类。每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接 口的实现。当使用者调用了代理对象所代理的接口中的方法的时候,这个调用的信息会被传递给InvocationHandler的invoke方法。在 invoke方法的参数中可以获取到代理对象、方法对应的Method对象和调用的实际参数。invoke方法的返回值被返回给使用者。这种做法实际上相 当于对方法调用进行了拦截。熟悉AOP的人对这种使用模式应该不陌生。但是这种方式不需要依赖AspectJ等AOP框架。

    下面的代码用来代理一个实现了List接口的对象。所实现的功能也非常简单,那就是禁止使用List接口中的add方法。如果在getList中传入一个实现List接口的对象,那么返回的实际就是一个代理对象,尝试在该对象上调用add方法就会抛出来异常。

    public List getList(final List list) {
        return (List) Proxy.newProxyInstance(DummyProxy.class.getClassLoader(), new Class[] { List.class },
            new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    if ("add".equals(method.getName())) {
                        throw new UnsupportedOperationException();
                    }
                    else {
                        return method.invoke(list, args);
                    }
                }
            });
     } 


    这里的实际流程是,当代理对象的add方法被调用的时候,InvocationHandler中的invoke方法会被调用。参数method就包含了调用的基本信息。因为方法名称是add,所以会抛出相关的异常。如果调用的是其它方法的话,则执行原来的逻辑。

    使用案例

    Java 反射API的存在,为Java语言添加了一定程度上的动态性,可以实现某些动态语言中的功能。比如在JavaScript的代码中,可以通过 obj["set" + propName]()来根据变量propName的值找到对应的方法进行调用。虽然在Java源代码中不能这么写,但是通过反射API同样可以实现类似 的功能。这对于处理某些遗留代码来说是有帮助的。比如所需要使用的类有多个版本,每个版本所提供的方法名称和参数不尽相同。而调用代码又必须与这些不同的版本都能协同工作,就可以通过反射API来依次检查实际的类中是否包含某个方法来选择性的调用。

    Java 反射API实际上定义了一种相对于编译时刻而言更加松散的契约。如果被调用的Java对象中并不包含某个方法,而在调用者代码中进行引用的话,在编译时刻就会出现错误。而反射API则可以把这样的检查推迟到运行时刻来完成。通过把Java中的字节代码增强、类加载器和反射API结合起来,可以处理一些对灵 活性要求很高的场景。

    在 有些情况下,可能会需要从远端加载一个Java类来执行。比如一个客户端Java程序可以通过网络从服务器端下载Java类来执行,从而可以实现自动更新 的机制。当代码逻辑需要更新的时候,只需要部署一个新的Java类到服务器端即可。一般的做法是通过自定义类加载器下载了类字节代码之后,定义出 Class类的对象,再通过newInstance方法就可以创建出实例了。不过这种做法要求客户端和服务器端都具有某个接口的定义,从服务器端下载的是 这个接口的实现。这样的话才能在客户端进行所需的类型转换,并通过接口来使用这个对象实例。如果希望客户端和服务器端采用更加松散的契约的话,使用反射API就可以了。两者之间的契约只需要在方法的名称和参数这个级别就足够了。服务器端Java类并不需要实现特定的接口,可以是一般的Java类。

    动态代理的使用场景就更加广泛了。需要使用AOP中的方法拦截功能的地方都可以用到动态代理。Spring框架的AOP实现默认也使用动态代理。不过JDK中的动态代理只支持对接口的代理,不能对一个普通的Java类提供代理。不过这种实现在大部分的时候已经够用了。

    参考资料

    展开全文
  • 在开发Java程序,尤其是Java EE应用的时候,总是免不了各种配置文件打交道。以Java EE中典型的S(pring)S(truts)H(ibernate)架构来说,Spring、Struts和Hibernate这三个框架都有自己的XML格式的配置文件。这些配置...
  • Java反射动态代理

    2015-09-22 16:43:21
    Java反射动态代理
  • 这是很全的关于java反射与动态代理方面的书,并且配有源代码,在平台框架开发方面会经常用得着
  • java反射动态代理

    2011-08-04 19:54:51
    java反射动态代理,详细说明反射和动态代理的方法和使用!
  • java反射机制与动态代理java反射机制与动态代理
  • 几个Java反射动态代理的小例子。可以学习如何通过Java的反射机制实例化对象、调用对象的方法、操作对象的私有成员变量、改变数组中的某项的值、改变数组大小等;可以学习Java的动态代理模式、学习Java工厂模式以及...
  • java语言反射与动态代理学习笔记
  • Java反射机制与动态代理 浪曦 Java Reflection API 简介 及动态代理
  • java反射动态代理

    2011-12-01 00:14:08
    java反射机制的分析,动态代理的分析实现。有详细的代码实例,适合学习。
  • Java 反射-动态代理

    2016-04-26 16:49:09
    Java反射机制提供了动态代理的封装。动态代理可以对原本实现的方法进行附加操作,比如修改这个方法的返回值、修改传入的参数、在方法执行前后做别的操作或者干脆完全替换这个方法都是可以实现的,唯一的缺憾是只支持...
  • java反射动态代理

    2013-01-22 22:13:18
    本文档时关于java反射及其实现的动态代理的介绍,主要结合经典实例进行说明
  • java反射动态代理详解

    千次阅读 2017-09-29 09:50:05
    动态代理 反射
  • JAVA反射机制与动态代理PPT............
  • 基础 | Java反射与动态代理

    千次阅读 2018-11-01 10:43:18
    动态代理作为Java反射的主要应用之一,其在多种JavaEE框架中均有使用,如Spring框架中AOP的实现原理就是动态代理,面试中提到AOP也必定会问 「谈谈对动态代理的理解?」 相关问题,在此做一个梳理总结。 谈谈对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 94,966
精华内容 37,986
关键字:

java反射与动态代理

java 订阅