元数据引擎设计(3)

前边介绍了元数据在系统设计和平台相关代码生成中的应用,本节介绍元数据的运行时模型,这部分也是整个元数据中最复杂的部分。

7.4.1  实体元数据运行时模型

元数据中定义了很多丰富的属性,但并不是元数据所有的属性都对运行时系统有用,而且有的属性也不应该放到运行时模型中,图7.9是运行时的元数据模型。

图7.9  运行时的元数据模型

DataTypeEnum是数据类型枚举,LinkTypeEnum是关联类型枚举,EntityFieldModelInfo为实体字段模型,EntityModelInfo为整体的实体元数据模型。可以看到实体字段模型中去掉了实体元数据中的“CascadeType”、“Constrained”、“Inverse”等属性,这些字段是Hibernate平台特有的,所以是不能放到运行时模型中的。

为了解析元数据文件以生成运行时元数据模型,我们开发了元数据解析器类EntityMetaDataParser(在包com.cownew.PIS.framework.common.metaDataMgr下),此类对外提供了一个静态方法:public static EntityModelInfo xmlToBean(Document doc)。将元数据XML文件的Dom4j对象Document 作为参数调用,返回值就是这个实体元数据的模型EntityModelInfo。因为XML文件中包含运行时元数据模型不需要的东西,所以此处不能使用XStream等OXMapping工具,而是使用Dom4j完成XML的解析。

7.4.2  分包及命名规范

在多层架构中,各个层之间有自己独立的不应被其他层访问的类,也有在层之间共享的类。对这些不同共享层次的类进行分包可以保证清晰的系统分层,也可以简化各层的配置安装。在案例系统中分为4种包:应用服务器包、Swing Client端包,Web Client端包,公共包。比如,有一个提供天气预报服务的Remoting Service,定义了服务接口IWeatherForecast,此服务接口是应用服务器、Swing Client、Web Client都要访问的,所以要将它放到公共包中;此接口的实现类WeatherForecastImpl只有应用服务器需要,因此定义在应用服务器包中;如果编写了一个Swing客户端WeatherForecastUI访问此服务,WeatherForecastUI就要定义在Swing Client端包中;如果编写一个Web页面,此页面有WeatherForecastForm和WeatherForecastAction两个类,这两个类就要放到Web Client端包中。在案例系统中,应用服务器包命名为bizLayer、

为了简化系统的开发及规范文件管理,案例系统对文件目录结构做了如下约定,如果实体元数据DemoEntity的名称(name)为DemoEntity,包名(packageName)为com.cownew. Demo,那么:

l   生成的hbm配置文件DemoEntity.hbm.xml保存在com.cownew.Demo.bizLayer目录下。

l   生成的JavaBean文件必须以实体名加“Info”命名,即DemoEntityInfo.java,它保存在com.cownew.Demo.common目录下。

l   此实体对应的DAO实现接口IDemoEntityDAO保存在com.cownew.Demo.bizLayer目录下。

l   此实体对应的DAO实现类DemoEntityDAOImpl保存在com.cownew.Demo.bizLayer目录下。

l   访问此接口的Swing客户端文件保存在com.cownew.Demo.client目录下。

l   访问此接口的Web端源码保存在com.cownew.Demo.web目录下。

前三条是必须遵守的规范,其他是建议遵守的规范。

系统运行时可能需要根据实体的JavaBean得到其对应的接口或者根据元数据的位置得知接口的位置,只要根据上述规则就可以在JavaBean、接口、元数据之间互相转换。为了简化此操作,系统提供了一个工具类NameUtils,位于包com.cownew.PIS. framework.common.metaDataMgr下,各个方法的作用如下。

l   public static String getVOClassName(String entityPath):将实体路径名转化为VO类名,比如getVOClassName("/com/cownew/Person.emf")将返回“com.cownew.common. PersonInfo ”。

l   public static String getPackageName(String entityPath):从实体路径名得到包路径名,比如getPackageName("/com/cownew/Person.emf")将返回“com.cownew”。

l   public static String getEntityName(String entityPath):从实体路径名得到实体名,比如getEntityName("/com/cownew/Person.emf")将返回“Person”。

l   public static String getEntityPath(String infoClassName):将VO类名转化为实体路径名,比如getEntityPath("com.cownew.common.PersonInfo")将会返回“/com/cownew/ Person.emf”。

7.4.3  元数据加载器接口

元数据加载器最基本的功能就是根据给出的元数据路径返回对应的元数据运行时模型,比如调用者想得到“人员”元数据运行时模型,只要将“/com/cownew/PIS/basedata/ Person.emf”作为参数传递给元数据加载器,加载器就可以返回对应于“人员”的EntityModelInfo类的实例。

为了方便调用,元数据加载器还提供一些辅助功能,比如根据VO类加载元数据、根据VO类名加载元数据、一次性加载系统中所有的元数据模型。元数据的解析是非常耗时且耗用内存的,最好提供元数据缓存以及缓存的持久化功能。

【例7.3】设计元数据加载器接口。

代码如下:

// 元数据加载器接口

public interface IMetaDataLoader

{

    /**

     * 根据元数据路径加载元数据运行时模型

     */

    public EntityModelInfo loadEntityByEntityPath(String path) throws
        MetaDataException;

   

    /**

     * 根据VO类加载元数据运行时模型

     */

    public EntityModelInfo loadEntityByVOClass(Class voClass) throws
        MetaDataException;

   

    /**

     * 根据VO类名加载元数据运行时模型

     */

    public EntityModelInfo loadEntityByVOClass(String voClass) throws
        MetaDataException;

   

    /**

     * 加载所有的实体元数据的path,List中元素的类型为String

     */

    public List loadAllEntityPath() throws MetaDataException;

   

    /**

     * 保存元数据缓存

     */

    public void saveCache();

}

7.4.4  元数据热部署

元数据的热部署指的是当对元数据进行修改以后,无须重启服务器就能在系统中得到修改以后的运行时元数据模型。元数据的热部署功能主要是考虑到应用服务器的启动过程以及Spring、Hibernate等的初始化过程都是需要一定的时间的,如果开发人员每次对元数据进行修改都需要重启服务器就会降低开发效率。

7.4.5  元数据部署方式

元数据在系统中存在的方式可以有3种:①元数据和.class二进制字节码文件放到一起;②把metadata文件夹直接放到系统的目录下;③把所有元数据单独打包成一个jar文件。

元数据是和二进制字节码文件用途不同的文件,如果将它们混放则不利于管理,第一种方式很自然地被否决了。

第二种方式将元数据单独管理,比第一种方式具有优势。当元数据数量变多以后,metadata文件夹占据的空间也会变大,从文件夹中检索文件的速度也会较慢。

第三种方式将元数据打包,减小了元数据占据的空间并且加快了文件的检索速度。但是在开发环境中采用此方式的话,开发人员每次新增、删除或者修改元数据以后都要对元数据重新打包,这是非常低效和不现实的。

为了同时兼顾开发环境和运行环境的要求,元数据引擎将同时支持第二、第三种方式。当处于开发环境时就采用第三种方式,当处于正式运行环境的时候则采用第二种方式。具体采用哪种方式可以在配置文件中配置。

为了提高元数据的加载速度,元数据在客户端和服务器端各存在一份,并且客户端和服务器端都有自己的元数据加载器实例。

<!-- page -->

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值