Java 反射和动态代理_第1页
Java 反射和动态代理_第2页
Java 反射和动态代理_第3页
Java 反射和动态代理_第4页
Java 反射和动态代理_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java Web分层架构类一、 类的生命周期在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。1、类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前链接就是把二进制数据组装为可以运行的状态。2、链接分为校验,准备,解析这3个阶段a)校验一般用来确认此二进制文件是否适合当前的JVM(版本);b)准备就是为静态成员分配内存空间,并设置默认值。c)解析指的是

2、转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)。3、完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。当没有任何引用指向Class对象时就会被卸载,结束类的生命周期。二、类加载器  在java中有三种类类加载器。1)Bootstrap ClassLoader此加载器采用c+编写,一般开发中很少见。2)Extension ClassLoader用来进行扩展类的加载,一般对应的是jrelibext目录中的类3)AppClassLoader加载classpath指定的类,

3、是最常用的加载器。同时也是java中默认的加载器。反射一、反射的概念: 主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。通常我们创建一个对象,只需要一句话new,但是new的前提是在知道类名的情况下,如果不知道类名,怎么得到这个类的对象呢?其实我们可以通过反射来实现。一个Java程序在运行时,可以获得任何一个类的字节码信息,包括类的修饰符(public,static等),基类(超类,父类),实现的接口,字段,方法等信息。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(

4、但不包括methods定义),并逆向生成其对象实体、或对其fields设值、或唤起其methods。  那么java是怎么实现这种机制的呢?Java的反射机制是通过反射API来实现的,主要包括以下几类: 1).Constructor类:用来描述一个类的构造方法 2).Field类:用来描述一个类的成员变量 3).Method类:用来描述一个类的方法. 4).Modifer类:用来描述类内各元素的修饰符 5).Array:用来对数组进行操作. Constructor,Field,Method这三个类都是JVM(虚拟机)在程序运

5、行时创建的,用来表示加载类中相应的成员。也就是说可以通过这些类来获取和改变反射类的所有成员。反射在框架中是最常用的手段。一个框架是先于调用者而存在的。当程序员用一个框架的时候,你写的什么类,框架怎么知道,就是通过java反射机制。Web.xml、Struts2.xml、applicationContext.xml、hibernate.cfg.xml、Peroson.hbm.xml、sqlMapperConfig.xml、PersonMapper.xml等配置文件中的class对应的字节码,都是通过反射来创建对象的。Param标签中的参数也是通过反射将其值设置到对象中。一个标准的javaBean

6、的反射叫做内省。mybatis的resultMap标签中,把结果集的和PO对象的属性一一对应起来,就能把结果集赋值给PO对象,这也是通过反省实现的。通过mapper.xml中指定的type,得到PO对象。二、反射机制的作用:1、反编译:.class->.java2、通过反射机制访问java对象的属性,方法,构造方法等;这样好像更容易理解一些,下边我们具体看怎么实现这些功能。三、SUN提供的有关反射机制中的类java.lang.Class;            

7、0;   java.lang.reflect.Constructor;java.lang.reflect.Field;        java.lang.reflect.Method;java.lang.reflect.Modifier;            很多反射中的方法,属性等操作我们可以从这四个类中查询。还是哪句话要学着不断的查询API,那才是我们最好的老师

8、。四、具体功能实现1、反射机制获取类有三种方法,我们来获取Employee类型1. /第一种方式:  2. Classc1 = Class.forName("Employee");  3. /第二种方式:  4. /java中每个类型都有class 属性.  5. Classc2 = Employee.class;  6.    7. /第三种方式:  8. /java语言中任

9、何一个java对象都有getClass 方法  9. Employeee = new Employee();  10. Classc3 = e.getClass(); /c3是运行时类 (e的运行时类是Employee)  2、创建对象:获取类以后我们来创建它的对象,利用newInstance:1. Class c =Class.forName("Employee");  2.  

10、60;3. /创建此Class 对象所表示的类的一个新实例  4. Objecto = c.newInstance(); /调用了Employee的无参数构造方法.  3、获取属性:分为所有的属性和指定的属性:a,先看获取所有的属性的写法: /获取整个类  1.             Class c = Class.forName("j

11、ava.lang.Integer");  2.               /获取所有的属性?  3.             Field fs = c.getDeclaredFields();  4.    

12、    5.               /定义可变长的字符串,用来存储属性  6.             StringBuffer sb = new StringBuffer();  7.   &

13、#160;         /通过追加的方法,将每个属性拼接到此字符串中  8.             /最外边的public定义  9.             sb.append(Modifier.toString(c.ge

14、tModifiers() + " class " + c.getSimpleName() +"n");  10.             /里边的每一个属性  11.             for(Field

15、 field:fs)  12.                 sb.append("t");/空格  13.                 sb.append(Modifier.toString(field

16、.getModifiers()+" ");/获得属性的修饰符,例如public,static等等  14.                 sb.append(field.getType().getSimpleName() + " ");/属性的类型的名字  15.     &#

17、160;           sb.append(field.getName()+"n");/属性的名字+回车  16.               17.       18.       

18、      sb.append("");  19.       20.             System.out.println(sb);      b,获取特定的属性,对比着传统的方法来学习:1. public static void 

19、;main(String args) throws Exception  2.               3. <span style="white-space:pre">  </span>/以前的方式:  4.     /* 5.   

20、60; User u = new User(); 6.     u.age = 12; /set 7.     System.out.println(u.age); /get 8.     */  9.            &#

21、160;  10.     /获取类  11.     Class c = Class.forName("User");  12.     /获取id属性  13.     Field idF = c.getDeclaredField("id"); 

22、 14.     /实例化这个类赋给o  15.     Object o = c.newInstance();  16.     /打破封装  17.     idF.setAccessible(true); /使用反射机制可以打破封装性,导致了java对象的属性不安全。  18.   

23、  /给o对象的id属性赋值"110"  19.     idF.set(o, "110"); /set  20.     /get  21.     System.out.println(idF.get(o);  22.   4、获取属性、方法,和构造方法 属性关键字含义Filed getFiel

24、d(String name)返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。Filed getFiled()返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。FiledgetDeclaredField(String name)  返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。FiledgetDeclaredFiled()返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。方法关键

25、字含义getDeclaredMethods()获取所有的方法getReturnType()获得方法的返回类型getParameterTypes()获得方法的传入参数类型getDeclaredMethod("方法名",参数类型.class,)获得特定的方法构造方法关键字含义getDeclaredConstructors()获取所有的构造方法getDeclaredConstructor(参数类型.class,)获取特定的构造方法父类和父接口含义getSuperclass()获取某类的父类getInterfaces()获取某类实现的接口     这样

26、我们就可以获得类的各种内容,进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。五、反射加配置文件,使我们的程序更加灵活        在设计模式学习当中,学习抽象工厂的时候就用到了反射来更加方便的读取数据库链接字符串等,当时不是太理解,就照着抄了。看一下.NET中的反射+配置文件的使用:             当时用的配置文件是ap

27、p.config文件,内容是XML格式的,里边填写链接数据库的内容:      <configuration>  1. lt;appSettings>  2. <add     key=""  value=""/>  3. lt;/appSettings>  4. </configuration>&#

28、160;  反射的写法:   1. assembly.load("当前程序集的名称").CreateInstance("当前命名空间名称".要实例化的类名);            这样的好处是很容易的方便我们变换数据库,例如我们将系统的数据库从SQL Server升级到Oracle,那么我们写两份D层,在配置文件的内容改一下,或者加条件选择一下即可,带来了很大的方便。  &#

29、160;      当然了,JAVA中其实也是一样,只不过这里的配置文件为.properties,称作属性文件。通过反射读取里边的内容。这样代码是固定的,但是配置文件的内容我们可以改,这样使我们的代码灵活了很多!  综上为,JAVA反射的再次学习,灵活的运用它,能够使我们的代码更加灵活,但是它也有它的缺点,就是运用它会使我们的软件的性能降低,复杂度增加,所以还要我们慎重的使用它。六、反射实现动态调用方法1、创建UserDao接口2、创建UserDaOracleImpl实现类3、创建UserDaoMySQLImpl实现类4、创

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

31、创建而成。静态代理由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。静态代理的实现步骤1、创建一个UserDao接口2、创建UserDaoMySQLImpl实现类3、创建UserDaoMyOracleImpl实现类4、创建UserService接口5、创建UserService接口的实现类UserServiceImpl6、创建测试类7、执行结果动态代理Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过

32、AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制。 jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。一、JDK代理(接口代理)1、JDK代理中的接口和类在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论