Hibernate Type 源码解析

本贴最后更新于 1643 天前,其中的信息可能已经时移世易

type 的类图

image

AssociationType: 关联类型的 type,主要用于外键等相关

IdentifierType: 主键相关的类型 type

BasicType: 基础类型,例如 long,int,string 等基础类型

type 注册

基础类型的注册器

/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.type; import java.io.Serializable; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.hibernate.HibernateException; import org.hibernate.internal.CoreLogging; import org.hibernate.internal.CoreMessageLogger; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.UserType; /** * A registry of {@link BasicType} instances * * @author Steve Ebersole */ public class BasicTypeRegistry implements Serializable { private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BasicTypeRegistry.class ); // TODO : analyze these sizing params; unfortunately this seems to be the only way to give a "concurrencyLevel" // 使用 ConcurrentHashMap 保证线程安全 private Map<String, BasicType> registry = new ConcurrentHashMap<>( 100, .75f, 1 ); private boolean locked; private TypeConfiguration typeConfiguration; public BasicTypeRegistry(TypeConfiguration typeConfiguration){ this(); this.typeConfiguration = typeConfiguration; } // 构造方法,用于注册各种对应的基础类型 public BasicTypeRegistry() { register( BooleanType.INSTANCE ); register( NumericBooleanType.INSTANCE ); register( TrueFalseType.INSTANCE ); register( YesNoType.INSTANCE ); register( ByteType.INSTANCE ); register( CharacterType.INSTANCE ); register( ShortType.INSTANCE ); register( IntegerType.INSTANCE ); register( LongType.INSTANCE ); register( FloatType.INSTANCE ); register( DoubleType.INSTANCE ); register( BigDecimalType.INSTANCE ); register( BigIntegerType.INSTANCE ); register( StringType.INSTANCE ); register( StringNVarcharType.INSTANCE ); register( CharacterNCharType.INSTANCE ); register( UrlType.INSTANCE ); register( DurationType.INSTANCE ); register( InstantType.INSTANCE ); register( LocalDateTimeType.INSTANCE ); register( LocalDateType.INSTANCE ); register( LocalTimeType.INSTANCE ); register( OffsetDateTimeType.INSTANCE ); register( OffsetTimeType.INSTANCE ); register( ZonedDateTimeType.INSTANCE ); register( DateType.INSTANCE ); register( TimeType.INSTANCE ); register( TimestampType.INSTANCE ); register( DbTimestampType.INSTANCE ); register( CalendarType.INSTANCE ); register( CalendarDateType.INSTANCE ); register( CalendarTimeType.INSTANCE ); register( LocaleType.INSTANCE ); register( CurrencyType.INSTANCE ); register( TimeZoneType.INSTANCE ); register( ClassType.INSTANCE ); register( UUIDBinaryType.INSTANCE ); register( UUIDCharType.INSTANCE ); register( BinaryType.INSTANCE ); register( WrapperBinaryType.INSTANCE ); register( RowVersionType.INSTANCE ); register( ImageType.INSTANCE ); register( CharArrayType.INSTANCE ); register( CharacterArrayType.INSTANCE ); register( TextType.INSTANCE ); register( NTextType.INSTANCE ); register( BlobType.INSTANCE ); register( MaterializedBlobType.INSTANCE ); register( ClobType.INSTANCE ); register( NClobType.INSTANCE ); register( MaterializedClobType.INSTANCE ); register( MaterializedNClobType.INSTANCE ); register( SerializableType.INSTANCE ); register( ObjectType.INSTANCE ); //noinspection unchecked register( new AdaptedImmutableType( DateType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( TimeType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( TimestampType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( DbTimestampType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( CalendarType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( CalendarDateType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( BinaryType.INSTANCE ) ); //noinspection unchecked register( new AdaptedImmutableType( SerializableType.INSTANCE ) ); } /** * Constructor version used during shallow copy * * @param registeredTypes The type map to copy over */ @SuppressWarnings({"UnusedDeclaration"}) private BasicTypeRegistry(Map<String, BasicType> registeredTypes) { registry.putAll( registeredTypes ); locked = true; } // 注册对应的基础类型 public void register(BasicType type) { register( type, type.getRegistrationKeys() ); } // 注册对应的基础类型最终实现方法 public void register(BasicType type, String[] keys) { // 判断是否加锁 if ( locked ) { throw new HibernateException( "Can not alter TypeRegistry at this time" ); } // 判断 type 是否为空 if ( type == null ) { throw new HibernateException( "Type to register cannot be null" ); } if ( keys == null || keys.length == 0 ) { LOG.typeDefinedNoRegistrationKeys( type ); return; } for ( String key : keys ) { // be safe... if ( key == null ) { continue; } //Use String#intern here as there's high chances of duplicates combined with long term usage: //just running our testsuite would generate 210,000 instances for the String "java.lang.Class" alone. //Incidentally this might help with map lookup efficiency too. key = key.intern(); LOG.debugf( "Adding type registration %s -> %s", key, type ); final Type old = registry.put( key, type ); if ( old != null && old != type ) { LOG.typeRegistrationOverridesPrevious( key, old ); } } } public void register(UserType type, String[] keys) { register( new CustomType( type, keys ) ); } public void register(CompositeUserType type, String[] keys) { register( new CompositeCustomType( type, keys ) ); } public void unregister(String... keys) { for ( String key : keys ) { registry.remove( key ); } } public BasicType getRegisteredType(String key) { return registry.get( key ); } public BasicTypeRegistry shallowCopy() { return new BasicTypeRegistry( this.registry ); } }

从 TypeFactory 中获取 type

/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.type; import java.io.Serializable; import java.util.Properties; import org.hibernate.MappingException; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoadingException; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.UserType; /** * Acts as the contract for getting types and as the mediator between {@link BasicTypeRegistry} and {@link TypeFactory}. * * @author Steve Ebersole * * @deprecated (since 5.3) No replacement, access to and handling of Types will be much different in 6.0 */ @Deprecated public class TypeResolver implements Serializable { private final TypeFactory typeFactory; private final TypeConfiguration typeConfiguration; public TypeResolver(TypeConfiguration typeConfiguration, TypeFactory typeFactory){ this.typeConfiguration = typeConfiguration; this.typeFactory = typeFactory; } // public TypeResolver() { // this( new BasicTypeRegistry(), new TypeFactory() ); // } // // /** // * @deprecated (since 5.3) // */ // @Deprecated // public TypeResolver(BasicTypeRegistry basicTypeRegistry, TypeFactory typeFactory) { // this.basicTypeRegistry = basicTypeRegistry; // this.typeFactory = typeFactory; // } // public TypeResolver scope(SessionFactoryImplementor factory) { // typeFactory.injectSessionFactory( factory ); // return new TypeResolver( basicTypeRegistry.shallowCopy(), typeFactory ); // } public void registerTypeOverride(BasicType type) { typeConfiguration.getBasicTypeRegistry().register( type ); } public void registerTypeOverride(UserType type, String[] keys) { typeConfiguration.getBasicTypeRegistry().register( type, keys ); } public void registerTypeOverride(CompositeUserType type, String[] keys) { typeConfiguration.getBasicTypeRegistry().register( type, keys ); } public TypeFactory getTypeFactory() { return typeFactory; } /** * Locate a Hibernate {@linkplain BasicType basic type} given (one of) its registration names. * * @param name The registration name * * @return The registered type */ public BasicType basic(String name) { return typeConfiguration.getBasicTypeRegistry().getRegisteredType( name ); } /** * See {@link #heuristicType(String, Properties)} * * @param typeName The name (see heuristic algorithm discussion on {@link #heuristicType(String, Properties)}). * * @return The deduced type; may be null. * * @throws MappingException Can be thrown from {@link #heuristicType(String, Properties)} */ public Type heuristicType(String typeName) throws MappingException { return heuristicType( typeName, null ); } /** * Uses heuristics to deduce the proper {@link Type} given a string naming the type or Java class. * <p/> * The search goes as follows:<ol> * <li>search for a basic type with 'typeName' as a registration key</li> * <li> * look for 'typeName' as a class name and<ol> * <li>if it names a {@link Type} implementor, return an instance</li> * <li>if it names a {@link CompositeUserType} or a {@link UserType}, return an instance of class wrapped into the appropriate {@link Type} adapter</li> * <li>if it implements {@link org.hibernate.classic.Lifecycle}, return the corresponding entity type</li> * <li>if it implements {@link Serializable}, return the corresponding serializable type</li> * </ol> * </li> * </ol> * * @param typeName The name (see heuristic algorithm above). * @param parameters Any parameters for the type. Only applied if built! * * @return The deduced type; may be null. * * @throws MappingException Indicates a problem attempting to resolve 'typeName' as a {@link Class} */ // 核心代码 public Type heuristicType(String typeName, Properties parameters) throws MappingException { // 如果为 basicType,z则直接获取 Type type = basic( typeName ); if ( type != null ) { return type; } try { // 如果Basic中未获取到,通过反射加载Type final ClassLoaderService classLoaderService = typeConfiguration.getServiceRegistry().getService( ClassLoaderService.class ); Class typeClass = classLoaderService.classForName( typeName ); if ( typeClass != null ) { return typeFactory.byClass( typeClass, parameters ); } } catch ( ClassLoadingException ignore ) { } return null; } }
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖
  • JPA
    17 引用 • 31 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...