ImageVerifierCode 换一换
格式:DOCX , 页数:20 ,大小:702.46KB ,
资源ID:4617862      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/4617862.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(Java 反射和动态代理.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

Java 反射和动态代理.docx

1、Java 反射和动态代理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,获悉其完整构造(但不包括me

4、thods定义),并逆向生成其对象实体、或对其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的反射叫做内省。mybatis的resultMap标签中,把结果集的和PO对象的属性一一对应起来

6、,就能把结果集赋值给PO对象,这也是通过反省实现的。通过mapper.xml中指定的type,得到PO对象。二、反射机制的作用:1、反编译:.class-.java2、通过反射机制访问java对象的属性,方法,构造方法等;这样好像更容易理解一些,下边我们具体看怎么实现这些功能。三、SUN提供的有关反射机制中的类java.lang.Class;java.lang.reflect.Constructor;java.lang.reflect.Field;java.lang.reflect.Method;java.lang.reflect.Modifier;很多反射中的方法,属性等操作我们可以从这四个

7、类中查询。还是哪句话要学着不断的查询API,那才是我们最好的老师。四、具体功能实现1、反射机制获取类有三种方法,我们来获取Employee类型1. /第一种方式:2. Classc1=Class.forName(Employee);3. /第二种方式:4. /java中每个类型都有class属性.5. Classc2=Employee.class;6. 7. /第三种方式:8. /java语言中任何一个java对象都有getClass方法9. Employeee=newEmployee();10. Classc3=e.getClass();/c3是运行时类(e的运行时类是Employee)2、

8、创建对象:获取类以后我们来创建它的对象,利用newInstance:1. Classc=Class.forName(Employee);2. 3. /创建此Class对象所表示的类的一个新实例4. Objecto=c.newInstance();/调用了Employee的无参数构造方法.3、获取属性:分为所有的属性和指定的属性:a,先看获取所有的属性的写法: /获取整个类1. Classc=Class.forName(java.lang.Integer);2. /获取所有的属性?3. Fieldfs=c.getDeclaredFields();4. 5. /定义可变长的字符串,用来存储属性6.

9、 StringBuffersb=newStringBuffer();7. /通过追加的方法,将每个属性拼接到此字符串中8. /最外边的public定义9. sb.append(Modifier.toString(c.getModifiers()+class+c.getSimpleName()+n);10. /里边的每一个属性11. for(Fieldfield:fs)12. sb.append(t);/空格13. sb.append(Modifier.toString(field.getModifiers()+);/获得属性的修饰符,例如public,static等等14. sb.append

10、(field.getType().getSimpleName()+);/属性的类型的名字15. sb.append(field.getName()+;n);/属性的名字+回车16. 17. 18. sb.append();19. 20. System.out.println(sb); b,获取特定的属性,对比着传统的方法来学习:1. publicstaticvoidmain(Stringargs)throwsException2. 3. /以前的方式:4. /*5. Useru=newUser();6. u.age=12;/set7. System.out.println(u.age);/ge

11、t8. */9. 10. /获取类11. Classc=Class.forName(User);12. /获取id属性13. FieldidF=c.getDeclaredField(id);14. /实例化这个类赋给o15. Objecto=c.newInstance();16. /打破封装17. idF.setAccessible(true);/使用反射机制可以打破封装性,导致了java对象的属性不安全。18. /给o对象的id属性赋值11019. idF.set(o,110);/set20. /get21. System.out.println(idF.get(o);22. 4、获取属性、

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

13、类或接口所声明的所有字段。方法关键字含义getDeclaredMethods()获取所有的方法getReturnType()获得方法的返回类型getParameterTypes()获得方法的传入参数类型getDeclaredMethod(方法名,参数类型.class,)获得特定的方法构造方法关键字含义getDeclaredConstructors()获取所有的构造方法getDeclaredConstructor(参数类型.class,)获取特定的构造方法父类和父接口含义getSuperclass()获取某类的父类getInterfaces()获取某类实现的接口 这样我们就可以获得类的各种内容,

14、进行了反编译。对于JAVA这种先编译再运行的语言来说,反射机制可以使代码更加灵活,更加容易实现面向对象。五、反射加配置文件,使我们的程序更加灵活在设计模式学习当中,学习抽象工厂的时候就用到了反射来更加方便的读取数据库链接字符串等,当时不是太理解,就照着抄了。看一下.NET中的反射+配置文件的使用:当时用的配置文件是app.config文件,内容是XML格式的,里边填写链接数据库的内容:1. lt;appSettings2. 3. lt;/appSettings4. 反射的写法: 1. assembly.load(当前程序集的名称).CreateInstance(当前命名空间名称.要实例化的类名

15、);这样的好处是很容易的方便我们变换数据库,例如我们将系统的数据库从SQL Server升级到Oracle,那么我们写两份D层,在配置文件的内容改一下,或者加条件选择一下即可,带来了很大的方便。当然了,JAVA中其实也是一样,只不过这里的配置文件为.properties,称作属性文件。通过反射读取里边的内容。这样代码是固定的,但是配置文件的内容我们可以改,这样使我们的代码灵活了很多! 综上为,JAVA反射的再次学习,灵活的运用它,能够使我们的代码更加灵活,但是它也有它的缺点,就是运用它会使我们的软件的性能降低,复杂度增加,所以还要我们慎重的使用它。六、反射实现动态调用方法1、创建UserDao

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

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

18、于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习的是其底层是怎么样的一个原理,而AOP的原理就是java的动态代理机制。 jdk动态代理和cglib动态代理。两种方法同时存在,各有优劣。jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用

19、。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。一、JDK代理(接口代理)1、JDK代理中的接口和类在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的。每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口

20、的 invoke 方法来进行调用。我们来看看InvocationHandler这个接口的唯一一个方法invoke方法。Object invoke(Object proxy, Method method, Object args) throws Throwable我们看到这个方法一共接受三个参数,那么这三个参数分别代表什么呢?Object invoke(Object proxy, Method method, Object args) throws Throwableproxy:指代我们所代理的那个真实对象method:指代的是我们所要调用真实对象的某个方法的Method对象args:指代的是调

21、用真实对象某个方法时接受的参数2、JDK代理实现步骤1)、创建一个UserDao接口2)、创建UserDaoMySQLImpl实现类3)、创建UserDaoOracleImpl实现类4)、创建代理对象的工厂5)、创建测试类6)、执行结果二、 cglib代理JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生成框

22、架,使用字节码技术生成代理类,比使用Java反射效率要高。引入两个JAR文件:cglib.jar和asm.jar1、cglib代理中的接口和类定义一个拦截器。在调用目标方法时,CGLib会回调MethodInterceptor接口方法拦截,来实现你自己的代理逻辑,类似于JDK中的InvocationHandler接口。参数:Object为由CGLib动态生成的代理类实例,Method为上文中实体类所调用的被代理的方法引用,Object为参数值列表,MethodProxy为生成的代理类对方法的代理引用。返回:从代理实例的方法调用返回的值。其中,methodProxy.invokeSuper(obj,arg):调用代理类实例上的proxy方法的父类方法2、cglib代理实现步骤1)、创建一个UserDao接口2)、创建UserDaoMySQLImpl实现类3)、创建UserDaoOracleImpl实现类4)、创建代理对象的工厂4)、创建测试类6)、执行结果

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1