软件项目实训及课程设计指导——如何应用Java反射技术灵活地创建程序类的对象实例
1、如何应用属性配置文件实现对系统中的配置信息进行读写操作
Java中的属性配置文件主要可以作为软件应用系统及项目的配置文件,比如许多J2EE的开源框架系统中都提供了属性配置文件作为该应用框架的对外配置文件——如实现O/R Mapping技术的Hibernate应用框架中的hibernate.properties和Log4J日志系统中的log4j.properties、Struts2应用框架中的struts.properties等属性配置文件。
在属性配置文件中一般是以“名字(键)—值对”的方式进行存储,请见下图所示的Struts2框架中的struts.properties文件内容的示例图示。
利用JDK系统库中的java.util.Properties类中的load方法可以加载属性文件和利用Properties类中的getProperty方法获得属性文件中的指定属性项目。但要注意加载属性文件的两种不同的形式:
(1)利用Class类中的getResourceAsStream方法
Class类中的getResourceAsStream方法是查找具有给定名称的资源,返回 InputStream类型的对象实例。但要注意getResourceAsStream方法是相对于”/”根路径下的位置,这样的路径在J2EE Web应用系统的环境下是指定为绝对路径,如果不以”/“开头, 则路径是相对于这个类所在的包——也就是表示从当前类的classPath路径找指定的文件。
(2)利用Class类中的getResource方法
Class类中的getResource方法是查找带有给定名称的资源路径并返回一个URL类型的对象实例。下图所示的程序代码实例是示例项目银行账户信息管理系统中的ClassNameConfig类的完整代码示例截图,其中利用static语句块完成对属性文件的一次性加载以提高效率——产生出单例设计模式的编程应用效果,然后再提供getProperty方法获得指定属性项目的内容。
2、如何实现对存储在XML格式的配置文件中的配置信息进行读写操作
(1)Java属性配置文件的方式所存在的问题
由于Java属性配置文件是采用“名字(键)—值对”的方式进行存储,因此无法体现各个“名字(键)”之间的层次关系和树形结构,也就无法表达复杂的数据关系,从而导致在实际应用中受到一定的限制。
由于XML格式的标准化和XML标签数据能够体现数据之间的层次关系,因此应用XML格式的配置文件能够表达树形结构的复杂层次性的配置数据关系,能够体现系统中的各个配置数据之间的层次性,可以应用于逻辑关系更复杂的应用场景中。
(2)在项目中采用XML格式的配置文件代替属性配置文件
由于在软件应用系统的配置信息中,各个配置数据之间一般都有一定的层次关系(如父子、前后等);同时为了能够达到与系统平台无关的配置应用要求。因此,对示例项目银行账户信息管理系统中的配置信息文件从原来应用Java属性配置文件的方式重构为XML格式的系统配置文件。下图所示为示例项目银行账户信息管理系统中的配置文件classNameConfig.xml的内容片段的图示。
(3)应用JDom实现对XML配置文件进行解析
JDom是一个开源项目,它基于树型结构,利用纯Java的技术对XML文档实现解析、创建、处理和序列化以及多种操作;并充分利用了Java平台中的优秀的特征,如:方法重载、回收机制,和后台处理等提高处理的效率。如下示图为JDom官方网站中提供的下载JDom系统库的页面内容的局部截图。
因此,在示例项目银行账户信息管理系统的项目中决定采用JDom系统库实现对XML格式的配置文件进行解析。
(4)在项目中添加JDom的系统包文件
读者可以在JDom官方网站中提供的下载JDom系统库文件的页面中下载JDOM的JAR包文件jdom.jar,然后再将该jdom.jar文件加入到项目的类路径中。最后的操作结果请见下图所示。
然后再对项目中的ClassNameConfig类的代码进行重构、并利用JDom 系统API实现对classNameConfig.xml配置文件中的XML配置信息进行解析。为了避免影响使用ClassNameConfig类的其它程序类代码产生被动地修改,重构后的程序代码对外的接口getProperty方法不变。重构后的代码请见下图所示。
3、利用Java反射技术动态创建程序类的对象实例
(1)Java反射(Reflection)机制主要提供的功能
Java程序员充分地应用反射技术,能够在程序代码中实现在运行时判断任意一个对象所属的类类型、也能够在运行时构造任意一个类的对象实例,当然还能够在运行时判断任意一个类所具有的成员变量和方法(通过反射甚至可以调用类中的private方法)和在运行时调用任意一个类对象实例中的方法。
(2)利用Java反射技术动态创建对象实例的基本步骤
首先要获取一个要操作的类的对象,该对象属于java.lang.Class类的实例;然后再通过Class类中的newInstance方法动态构造出对应的类的对象实例。下图所示为示例项目银行账户信息管理系统中动态创建出AccountInfoManageInterface接口对象的工厂类AccountInfoManageFactory的代码片段。
由于在AccountInfoManageFactory工厂类的newAccountInfoManageBean方法只接收需要创建对象的类名称,因此可以向该方法传递同一接口的不同实现类名称,也就可以实现创建出不同类的对象实例。提高了工厂类在创建对象的灵活性和代码的可扩展性。
4、如何应用依赖注入技术高效地创建出对象实例
(1)Spring 应用框架中的控制反转模式和依赖注入技术
1)Spring应用框架中的控制反转模式
Spring应用框架的核心在于其提供的控制反转(IoC,Inversion of Control)容器,而IoC容器最主要实现的功能则是为软件应用系统提供对象管理方面的实现技术。并帮助软件应用系统的开发者实现对软件应用系统中的各个类进行对象实例化、建立对象之间的依赖关系、对象的缓存等与生命周期有关的各个方面的管理功能。
利用控制反转模式能够有效地减少对象的请求者对服务提供者的特定实现逻辑的依赖,因为应用系统中的各个组件类不再需要去查找或是实例化它们所依赖的其它的目标组件类的对象实例。
2)Spring 应用框架中的依赖注入技术
依赖注入(DI,Dependency Injection)技术是对控制反转IoC的具体实现技术,因为它更加准确地描述了控制反转IoC的设计理念。单纯从名字上理解依赖注入的基本意思是:组件之间的依赖关系由容器在运行期决定,也就是由容器(如Spring框架的运行系统程序)动态地创建出目标类的对象实例、并将某种依赖关系注入到目标组件类中。
IoC和DI的技术本质都是希望能够改变软件应用系统中程序类之间的各种“依赖”关系——程序类之间的依赖关系由原来直接依赖“目标组件类”改变为依赖于“容器”。
5、Spring框架中的控制反转模式与GOF工厂模式在实现方式方面的不同点
IOC 是一种使应用程序“逻辑外在化”的设计模式——因为提供服务的组件类的对象实例是被“注入”的而不是被“直接写入”到请求者(客户端)的代码中,并将组件类之间的依赖关系转移到系统外部的配置文件中,避免在调用类中硬编码实现相关的功能。这样将能够大大地减少服务的请求者对服务提供者的特定实现逻辑的依赖——提高了软件应用系统中的各个组件类的可移植性和可重用度。
Spring应用框架通过依赖注入技术实现了控制反转模式,而依赖注入技术的具体实现则又是借用Java语言中的反射技术——Spring IoC容器核心程序依据开发人员在XML配置文件中所定义的类名称和对应的对象名称,利用反射技术动态地创建出该类的对象实例,并借助于成员属性的set方法或者构造方法动态地将所创建出的对象实例注入到目标类中。
6、利用Spring 控制反转模式以XML配置文件的方式定义需要创建的目标对象
(1)应用IoC进行软件应用系统开发时的基本要求
首先,软件应用系统的开发人员不应该再在程序代码中直接创建出目标类的对象实例,但是需要描述出创建它们的方式和要求。
其次,在服务请求者的程序代码中不直接完成对服务提供者类对象的实例化工作,而只需要在XML配置文件中描述出所需要的服务组件有关的信息。
最后,程序在运行时,由Spring 应用框架中的IoC容器程序负责创建出这些对象和将这些对象关联在一起。
(2)利用Spring 应用框架中的依赖注入技术创建对象实例
下图所示为某个项目中的Spring IoC容器中的XML配置文件定义的片段截图,在Spring应用框架中提供有属性注入(Setter Injection)和构造方法注入(Constructor Injection),并通过标签定义某个类的对象实例的基本信息。
采用Spring应用框架中依赖注入技术能够更简洁地实现GOF工厂模式相同的效果,因为Spring应用框架系统程序会对开发人员所提供的XML配置文件中的各个配置项目信息进行解析,然后利用Java语言中的反射技术,并根据在XML配置文件中所给出的类名生成对应的类对象实例。
如何应用GOF设计模式中的创建型模式实现松耦合地创建对象实例
项目及课程设计指导——如何合理创建对象实例以降低程序类之间关系的耦合度
领取专属 10元无门槛券
私享最新 技术干货