hibernate涂鸦(2)——reflection反射
org.hibernate.annotations.common.reflection.java.JavaXPackage extends JavaXAnnotatedElemen: Hibernate对Package的适配(Adapter pattern)
? -- javaReflectionManager: 父类属性
? -- annotatedElement: 父类属性
? -- public JavaXPackage(Package, JavaReflectionManager): 直接调用同参数super构造函数,分别赋值给annotatedElement和javaReflectionManager
?
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),分别赋值给annotatedElement和javaReflectionManager,赋值clazz和typeEnvironment
?
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配置的环境,会在JPAMetadataProvider的xmlContext属性初始化时被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名字
?
?
org.hibernate.annotations.common.reflection.java.JavaMetadataProvider: 默认构造函数,在JPAMetadataProvider的metadataProvider属性初始化被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: 唯一参数构造函数,仅在JavaMetadataProvider的getAnnotationReader方法里被new出来,封装了一个ann元素的对象,代理该对象上访问ann的方法。
? -- annotatedElement: 封装一个具有ann定义的类型元素
?
org.hibernate.cfg.annotations.reflection.JPAMetadataProvider: 默认构造函数,在Configuration的reset方法中被new出来,并设置给JavaReflectionManager的metadataProvider,在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: 仅在JPAMetadataProvider的getAnnotationReader方法里被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): 唯一构造函数:
? -- 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其他情况,annotations和annotationsMap包含所有在annotatedElement上存在的ann。?
org.hibernate.annotations.common.reflection.java.JavaReflectionManager.TypeKey: 静态私有内部类,一个<Type, TypeEnvironment>的Pair结构
?
org.hibernate.annotations.common.reflection.java.JavaReflectionManager: static初始块里log一下annotation的版本,在Configuration的reset方法中被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并返回。
?
?
?
?
?