`
ratlsun
  • 浏览: 49242 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

hibernate涂鸦(2)——reflection反射

阅读更多

org.hibernate.annotations.common.reflection.java.JavaXPackage extends JavaXAnnotatedElemen: Hibernate对Package的适配(Adapter pattern

  -- javaReflectionManager: 父类属性

  -- annotatedElement: 父类属性

  -- public JavaXPackage(Package, JavaReflectionManager): 直接调用同参数super构造函数,分别赋值给annotatedElementjavaReflectionManager

 

org.hibernate.annotations.common.reflection.java.JavaXClass extends JavaXAnnotatedElement: Hibernate对Class的适配(Adapter pattern

  -- javaReflectionManager: 父类属性

  -- annotatedElement: 父类属性

  -- clazz: 同父类的annotatedElement

  -- typeEnvironment

  -- public JavaXClass(Class, TypeEnvironment, JavaReflectionManager): 调用super(Class, JavaReflectionManager),分别赋值给annotatedElementjavaReflectionManager,赋值 clazztypeEnvironment

 

org.hibernate.annotations.common.reflection.java.generics.IdentityTypeEnvironment implements TypeEnvironment: 饥饿单例,描述唯一类型环境,每个Type都返回它本身

  -- public Type bind(Type): 接口方法,返回Type本身。

 

org.hibernate.annotations.common.reflection.java.generics.TypeSwitch<T>: 对根据Type进行条件分支的代码进行抽象后得到的默认模板类,使用时继承该类并覆盖其中某些针对具体Type的方法。

  -- public final T doSwitch(Type): 核心方法,根据Type不同switch到其他分支方法,并返回指定的T。

 

org.hibernate.cfg.annotations.reflection.XMLContext.Default: 内部类,默认构造函数,描述配置的默认值

  -- accessType: 配置持久化工具如何访问对象的属性,AccessType 为枚举类型:PROPERTY|FIELD,参考一篇对2种方式分析利弊的文章(回帖也同样不错)
  -- String packageName: 包名
  -- String schema: db schema
  -- String catalog: db catalog
  -- Boolean metadataComplete: 是否忽略annotation设置,true表示只采用xml设置,忽略ann设置。
  -- Boolean cascadePersist: 是否级联持久化
  -- Boolean delimitedIdentifier: 是否使用db的标识界定字符

  -- public void override(Default): 用传入的Default对象的各个属性值(如果存在)更新本对象的属性值。

  -- public boolean canUseJavaAnnotations(): 返回metadataComplete 的非,或者在metadataComplete 为null是返回true,表示不忽略ann设置。

 

org.hibernate.cfg.annotations.reflection.XMLContext: 描述整个xml配置的环境,会在JPAMetadataProviderxmlContext 属性初始化时被new出来。  

  -- boolean hasContext: 指示Context是否被建立起来了,属性默认值为false。

  -- globalDefaults: 在 addDocument 方法里被new Default 出来并设置,全局的默认配置。

  -- classOverriding: Map<String, Element>,通过className找到dom4j的节点元,包括"entity","mapped-superclass","embeddable"以及各个地方定义的"entity-listener"。

  -- defaultEntityListeners: List<String>,所有className的列表,只包括"persistence-unit-defaults"节点上 定义的"entity-listener"。

  -- defaultElements: List<Element>,所有dom4j节点元素的列表,只放了root节点。

  -- defaultOverriding: Map<String, Default>,通过className找到作用在它之上的Default 默认配置,每一个"entity","mapped-superclass","embeddable"都有自己的Default对象。

  -- public Default getDefault(String): 针对传入的className得到从defaultOverriding 中得到该类的默认配置。

  -- public Element getXMLTree(String): 针对传入的className得到从classOverriding 中得到该类的dom4j节点。

  -- public List<String> addDocument(Document): 核心方法(其他都是get属性的方法),把dom4j的doc(JPA的orm.xml)加入的当前context中,并且返回doc中存在的所有class名字

  1. hasContext置为true
  2. 如果root节点("entity-mappings")包含"persistence-unit-metadata"子节点:并且如果globalDefaults 为null,则new Default对象赋值给globalDefaults,然后分析该子节点:
    1. 将"xml-mapping-metadata-complete"子子节点的值赋值给 globalDefaults .metadataComplete ,不存在的话默认为false;
    2. 如果"persistence-unit-defaults"子子节点存在,则分别读取各个子节点并赋值 globalDefaults . "schema","catalog","access": accessType,"cascade-persist","delimited-identifiers";遍历"entity-listeners"子子节点下所有"entity-listener"节点,取得"class"属性值,如果classOverriding 包含了该属性值:并且如果从classOverriding根据该属性值取出的element节点名字是"entity-listener"的话就log该listener的重复定义然后继续遍历下一个,else则抛出IllegalStateException 说明已经定义成entity的类不能再被定义为listener,导致遍历终止;最后将listener放入classOverriding 中,而listenerClassName 放入defaultEntityListeners 列表中。
  3. 用root节点下面的"package","schema","catalog","access"节点构造一个Default 对象传入Step5 的遍历过程;
  4. 把root节点("entity-mappings")放入到defaultElements 列表中;
  5. 分别遍历root下的"entity","mapped-superclass","embeddable"子节点:
    1. 取得每个子节点的"class"属性值,并与root节点下面的"package"节点提供的 默认包名构成类的全限定名字,如果classOverriding 包含了该className则抛出IllegalStateException 说明已经定义成entity的类不能再被定义为另外的entity;else则将该子节点元素放入classOverriding 中;
    2. 如果该子节点定义了"metadata-complete"节点或者"access"节点,取出这些节点值并覆盖Step3 传入的Default 对象,将这个变化后的Defualt 对象放入defaultsOverriding 中;
    3. 遍历"entity-listeners"子子节点下所有"entity-listener"节点,取得"class"属性值,并与root节点下面的"package"节点提供的 默认包名构成类的全限定名字,如果classOverriding 包含了该className:并且如果从classOverriding根据该属性值取出的element节点名字是"entity-listener"的话就log该listener的重复定义然后继续遍历下一个,else则抛出IllegalStateException 说明已经定义成entity的类不能再被定义为listener,导致遍历终止;最后将listener放入classOverriding 中。
  6. 最终return一个包含所有"entity","mapped-superclass","embeddable"以及各个地方定义的"entity-listener"的className列表。

 

 

org.hibernate.annotations.common.reflection.java.JavaMetadataProvider: 默认构造函数,在JPAMetadataProvidermetadataProvider 属性初始化被new出来,对MetadataProvider 接口的最简单实现

  -- public Map<Object, Object> getDefaults(): 返回一个可系列化的并且immutable的空Map,即表明不存在default的metadata。

  -- public AnnotationReader getAnnotationReader(AnnotatedElement): 用传入的有ann的元素构造一个JavaAnnotationReader 对象并return。

 

org.hibernate.annotations.common.reflection.java.JavaAnnotationReader: 唯一参数构造函数,仅在JavaMetadataProvidergetAnnotationReader 方法里被new出来,封装了一个ann元素的对象,代理该对象上访问ann的方法。

  -- annotatedElement: 封装一个具有ann定义的类型元素

 

org.hibernate.cfg.annotations.reflection.JPAMetadataProvider: 默认构造函数,在Configurationreset 方法中被new出来,并设置给JavaReflectionManagermetadataProvider,在 JavaMetadataProvider 之上增强了JPA metadata的功能(多了Default/XMLContext/cache以及提供一个特有的JPAOverridenAnnotationReader使得xml配置和ann配置可以统一处理 )。

  -- metadataProvider: transient,属性初始化时new JavaMetadataProvider 对象放入作为delegate被JPAMetadataProvider 代理(Proxy pattern ),

  -- xmlContext: metadata的context,属性初始化时new XMLContext 对象放入。

  -- cache: transient,Map<AnnotatedElement, AnnotationReader>: 缓存AnnotationReader 对象,可以根据被read的具有ann的元素来查找。

  -- public AnnotationReader getAnnotationReader(AnnotatedElement): 用传入的具有ann的元素在cache 里查找对应的Reader,找到则return;else找不到则判断xmlContext .hasContext() ,如果已经建立的context,则用传入的annotatedElement和xmlContext 一起构造出一个JPAOverridenAnnotationReader 对象并缓存后return,else没有建立起context,则调用被代理的metadataProvider .getAnnotationReader(传入的annotatedElemen) 方法得到一个JavaAnnotationReader 对象并缓存后return。

 

org.hibernate.cfg.annotations.reflection.JPAOverridenAnnotationReader: 仅在JPAMetadataProvidergetAnnotationReader 方法里被new出来,比JavaAnnotationReader 提供更复杂的功能:在调用AnnotationReader接口定义方法前会先执行initAnnotations 方法.

  -- annotatedElement: 封装一个具有ann定义的类型元素,代理了该对象上访问ann的方法。

  -- xmlContext: metadata的context,由JPAMetadataProvider 通过构造函数赋值。

  -- annotations: transient,包括annotatedElement上定义的所有ann的集合(有些ann是通过xml配置新构造的)数组,由initAnnotations 方法建立并填充。

  -- annotationsMap: transient,Map<Class, Annotation>,和annotations 数组放的东西一样,包括annotatedElement上定义的所有ann的集合(有些ann是通过xml配置新构造的),并且以ann的类型为key;同样由initAnnotations 方法建立并填充

  -- annotationToXml: static,Map<Class, String>,通过所有JPA定义的annotation找到对应的xml配置项。会在类初始化时被建立起来并初始化所有对应值。

  -- String className

  -- String propertyName

  -- propertyType: PropertyType 为枚举类型:PROPERTY/FIELD/METHOD

  -- public JPAOverridenAnnotationReader(AnnotatedElement, XMLContext): 唯一构造函数:

  1. annotatedElementxmlContext 赋值;
  2. 如果传入的element是Class类型,则对className 赋值;
  3. 如果传入的element是Field类型,则对className/propertyName分别赋值, propertyType置为Field ,并假设存在该field的get方法,取得Method对象后赋值给mirroredAttribute,如果方法不存在,NoSuchMethodException会被吃掉。
  4. 如果传入的element是Method类型 ,则对className赋值,如果这个Method是某个Field的get/is方法,那么propertyName 赋值为Field名字, propertyType置为PROPERTY,并假设存在这个field,取的Field对象后赋值给mirroredAttribute ;else情况 propertyName 赋值为Method名,propertyType 置为 METHOD。
  5. 其他类型的情况,则置 className/propertyName都为null。

  -- private void initAnnotations(): 根据 annotatedElement类型不同分别构造对应的 annotations 数组和annotationsMap以方便在read的时候可以直接读取到和orm.xml的配置融合后的ann

  • 如果className不null并且propertyName为null,说明是class类型的annotatedElement 构造的reader,则调用xmlContext .getXMLTree (className )得到dom4j节点,调用 xmlContext .getDefault (className )得到Default 配置,然后利用Default 对象和dom4j节点对象以及annotatedElement 上存在的所有ann构造出一个annotations 数组和一个annotationsMap,数组和map是一致的,存放规则为:不包含在 annotationToXml 的类型的ann,以及如果在context里已经通过xml配置了,则被这些xml配置盖后的ann;最后将xml里配置了的attributes,但在具体的class上却没有该field或者property的话,记录log,不做任何处理。
  • 如果className不null并且propertyName也不null,说明是Field/Method类型的annotatedElement 构造的reader,@TODO
  • 其他情况,annotationsannotationsMap 包含所有在 annotatedElement上存在的ann。

 

org.hibernate.annotations.common.reflection.java.JavaReflectionManager.TypeKey: 静态私有内部类,一个<Type, TypeEnvironment >的Pair结构

 

org.hibernate.annotations.common.reflection.java.JavaReflectionManager: static初始块里log一下annotation的版本,在Configurationreset 方法中被new出来,并设置给Configuration reflectionManager

  -- metadataProvider

  -- packagesToXPackages: Map<Package, JavaXPackage>

  -- xClasses: Map<TypeKey, JavaXClass>

  -- public XPackage packageForName(String) throws ClassNotFoundException: 根据传入的package名字(包中必须存在package-info.java文件)通过反射得到Package对象,把Package对象和this作为参数new出一个JavaXPackage;Package对象为key,JavaXPackage对象为value,在packagesToXPackages找key,找到返回;找不到 放value进packagesToXPackages并返回。

  -- public XClass classForName(String className, Class caller) throws ClassNotFoundException: toXClass(通过传入caller的CL使用反射得到Class对象)

  -- public XClass toXClass(Class): toXClass(传入的Class对象, IdentityTypeEnvironment 的实例)

  -- XClass toXClass(Type, TypeEnvironment): 构造一个能特殊处理Class和ParameterizedType两种Type的TypeSwitch<XClass>,其中对待Class的处理方法为:使用传入的Class和TypeEnvironment new一个TypeKey对象作为key,使用Class和TypeEnvironment以及this new一个JavaXClass对象作为value,在xClasses 里找该key,找到返回;找不到 放value进xClasses 并返回。

 

 

 

 

 

分享到:
评论

相关推荐

    struts2+hibernate整合例子——新闻管理系统

    总结来说,"struts2+hibernate整合例子——新闻管理系统"是一个典型的Java Web应用示例,展示了如何利用Struts2的MVC模式和Hibernate的ORM能力,实现对新闻数据的CRUD操作及高级查询。这个系统可能包含了Action类、...

    Dwr2+Struts2+Spring2.5+Hibernate3实战——用户登录注册系统

    《Dwr2+Struts2+Spring2.5+Hibernate3实战——用户登录注册系统》这篇文章探讨了如何利用四个主流的Java开发框架构建一个用户登录注册系统。Dwr2、Struts2、Spring2.5和Hibernate3各自扮演着关键的角色,共同实现了...

    hibernate 涂鸦版.zip

    hibernate 涂鸦版.zip,为html文件,我在达内达内培训时刘新福老师提供的内部资料,傻瓜式涂鸦教程,配合卡通人物的对话,将hibernate轻松调侃出来,非常非常非常适合初学者和经常容易遗忘基础关联细节问题的开发者...

    struts2+Spring+Hibernate帮助文档——中文.rar

    struts2+Spring+Hibernate帮助文档_中文 struts2+Spring+Hibernate帮助文档_中文 struts2+Spring+Hibernate帮助文档_中文 struts2+Spring+Hibernate帮助文档_中文

    JAVA 私塾笔记整理——反射机制(Reflection)

    在"JAVA私塾笔记整理——反射机制(Reflection)"这份文档中,我们将深入探讨反射机制的基础知识、用途和实现方式。 1. **反射机制的基本概念** 反射机制是Java提供的一种能够在运行时分析类和对象的能力。它允许...

    MyClipse6.0\Struts2,Spring与Hibernate整合应用,学生成绩管理系统

    《Struts2、Spring与Hibernate整合应用:学生成绩管理系统》 在IT行业中,构建一个高效、稳定的Web应用程序常常需要整合不同的框架。本项目“学生成绩管理系统”就是基于Struts2、Spring和Hibernate三大主流Java ...

    struts2+hibernate整合的例子——新闻管理系统

    Struts2和Hibernate是两种非常重要的Java Web开发框架,它们分别负责表现层和持久层的管理。Struts2是一款强大的MVC(Model-View-Controller)框架,它为Web应用程序提供了一种组织业务逻辑和控制流程的方式。而...

    Hibernate使用——入门

    **Hibernate使用——入门** Hibernate 是一个强大的开源对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。这篇博文将引导你入门Hibernate,理解其基本概念和使用方法。 **1. Hibernate概述** ...

    Hibernate 4——Hello World

    在本文中,我们将深入探讨如何使用Hibernate 4框架进行初步的“Hello World”实践。Hibernate是一个流行的开源对象关系映射(ORM)框架,它简化了Java应用程序与数据库之间的交互。通过将Java对象与数据库表之间的...

    Hibernate总结——课程管理

    在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本教程将深入探讨如何使用Hibernate来实现一个简单的课程管理系统,涵盖多对...

    Hibernate使用——自定义数据类型

    2. **实现Hibernate的Type接口**:这个接口是自定义数据类型的核心,它定义了如何在Java对象和SQL值之间进行转换。你需要实现`nullSafeGet()`和`nullSafeSet()`方法,分别用于从ResultSet中读取数据和将数据写入...

    7.1.1Hibernate的入门必备——文档和源码

    【标题】"7.1.1Hibernate的入门必备——文档和源码"主要涉及的是Java领域的一个重要ORM框架——Hibernate的基础学习。Hibernate是一种用于Java应用的开源对象关系映射(ORM)工具,它允许开发者将Java类与数据库表...

    Hibernate涂鸦

    【Hibernate涂鸦】是针对初学者和开发者设计的一份教程,旨在通过图形化的学习方法,帮助大家快速理解和掌握Hibernate框架的映射文件编写技巧。Hibernate是一个流行的关系对象映射(ORM)框架,它允许开发人员在Java...

    北大青鸟ACCP6.0 第三学期 Y2 JAVA方向 reflection 反射

    反射在很多框架和库中都有应用,如Spring框架的依赖注入,Hibernate的ORM映射,以及Java的动态代理(如`java.lang.reflect.Proxy`类)。 总结,北大青鸟ACCP6.0第三学期的JAVA方向反射课程旨在帮助学生掌握这一高级...

    hibernate原理小程序(反射)

    2. 对象的持久化:当我们要将Java对象保存到数据库时,Hibernate会使用反射调用对象的setter方法设置属性值,然后根据对象的状态决定是执行INSERT、UPDATE还是DELETE语句。同样,从数据库查询结果转换为Java对象时,...

    提升Hibernate性能的魔方——IronTrack SQL.pdf

    在提到提升Hibernate性能的魔方——IronTrack SQL时,我们必须首先了解IronTrack SQL的背景和功能。IronTrack SQL是基于Apache许可证的开源工具,通过与开源JDBC驱动p6spy合作,提供了一个增强的对基于Hibernate的...

    北大青鸟Hibernate单元练习项目——电影信息管理系统

    这是我花费4天的时间做的北大青鸟Hibernate单元练习项目。学Hibernate的时候没感觉很难,然后做小项目的时候才发现,有许多细节的地方不好处理。如何使用好Criteria限制查询条件、怎样用好和标签,怎样进行增加验证....

Global site tag (gtag.js) - Google Analytics