Hibernate源码分析

</pre><!--?xml version="1.0" encoding="UTF-8" standalone="no"?--><div style="font-family: Arial;font-size:14px;">Hibernate一般被我们作为数据库持久化工具使用,下面是我在使用过程中对工具使用过程中调试跟踪的一些记录。</div><div style="font-family: Arial;font-size:14px;"></div><div style="font-family: Arial;font-size:14px;">我们一般在applicationContext.xml里如上配置,打开类AnnotationSessionFactoryBean.java,看该类的构造函数及父类的构造函数</div><div style="font-family: Arial;font-size:14px;"><pre name="code" class="html"><bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="configLocation"]]>
            <value>classpath:hibernate.cfg.xml</value>
        </property>
</bean>



public AnnotationSessionFactoryBean() {
         setConfigurationClass(AnnotationConfiguration.class);
 }

<pre name="code" class="java">public AnnotationSessionFactoryBean() {
                setConfigurationClass(AnnotationConfiguration.class);
        }


        @Override
        public void setConfigurationClass(Class configurationClass) {
                if (configurationClass == null || !AnnotationConfiguration.class.isAssignableFrom(configurationClass)) {
                        throw new IllegalArgumentException(
                                        "AnnotationSessionFactoryBean only supports AnnotationConfiguration or subclasses");
                }
                super.setConfigurationClass(configurationClass);
        }




org.hibernate.cfg.Configuration  doConfig(File f)会使用hibernate.cfg.xml配置好之后调用buildSessionFactory()

org.springframework.beans.factory.InitializingBean  void afterPropertiesSet()方法可见,bean的配置参数设置之后,该函数会被调用 

org.springframework.orm.hibernate3.AbstractSessionFactoryBean 作为AnnotationSessionFactoryBean的父类实现了该接口,于是sessionFactory被构造出来。

public void afterPropertiesSet() throws Exception {
                SessionFactory rawSf = buildSessionFactory();
                this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);
                afterSessionFactoryCreation();
        }

我们在dao层一般使用getSession().load( id );getSession().save(obj);getSession().delete(obj)getSession().update( obj );等等方式实现CRUD,这些都会调用到org.session.impl.sessionImpl类下面的fireDelete(pram...),fireLoad(pram...),fireSaveOrUpdate(pram...)等方法,以delete为例子添加进去的deleteEventListener调用onDelete(DeleteEvent event )方法---》 public void  onDelete(DeleteEvent  event , Set  transientEntities )

EntityEntry entityEntry = persistenceContext.getEntry( entity );

                if ( entityEntry == null ) {
}
                else {
                        log.trace( "deleting a persistent instance" );

                        if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
                                log.trace( "object was already deleted" );
                                return;
                        }
                        persister = entityEntry.getPersister();
                        id = entityEntry.getId();
                        version = entityEntry.getVersion();
                }
deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), persister, transientEntities );

可以看出,需要现在持久层查找该实体,找不到需要添加到持久层,找到了就可以准备删除。然后跳转deleteEntity方法,

session.getActionQueue().addAction(newEntityDeleteAction(entityEntry.getId(),deletedState,version,entity,persister,isCascadeDeleteEnabled,session));查看该Action的excite方法,

final CacheKey ck;if (persister.hasCache() ) {ck = new CacheKey( ...);lock = persister.getCacheAccessStrategy().lockItem( ckversion );
}并锁定缓存中的该数据,下方代码显示,需再缓存中删除,但我看不出来persistenceContext.removeEntity()和cacheAccessStrategy.remove的区别,知道的还请告知。

          if ( !isCascadeDeleteEnabled && !veto ) {
                        persister.delete( id, version, instance, session );
                }
                
                final PersistenceContext persistenceContext = session.getPersistenceContext();
                EntityEntry entry = persistenceContext.removeEntry( instance );
                if ( entry == null ) {
                        throw new AssertionFailure( "possible nonthreadsafe access to session" );
                }
                entry.postDelete();

                persistenceContext.removeEntity( entry.getEntityKey() );
                persistenceContext.removeProxy( entry.getEntityKey() );
                
                if ( persister.hasCache() ) {
                        persister.getCacheAccessStrategy().remove( ck );
                }

而查询load不同,会涉及到sessionCache与secondLevelCache。

Object doLoad(final LoadEvent event,
                        final EntityPersister persister,
                        final EntityKey keyToLoad,
                        final LoadEventListener.LoadType options) {
Object entity = loadFromSessionCache( event, keyToLoad, options );
                        return entity;
                }

                entity = loadFromSecondLevelCache(event, persister, options);
                if ( entity != null ) {
                     return entity
             }
             return loadFromDatasource(event, persister, keyToLoad, options);
}

顺序是先一级缓存,然后二级缓存,然后数据库。在不同位置找到有不同处理,如果从数据库来,要将该实体添加至SessionCache里,如果从二级缓存来我看不出来做什么了。

暂时到这,

github: gitHub地址


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring和Hibernate是Java开发中非常常用的两个框架,下面简单介绍一下它们的源码分析。 1. Spring源码分析 Spring是一个轻量级的IoC和AOP框架,其中IoC主要是通过BeanFactory和ApplicationContext来实现的。在Spring的源码中,可以看到很多设计模式的运用,如工厂模式、单例模式、策略模式、代理模式等等,这些设计模式的运用使得Spring的代码更加灵活和易于维护。 其中BeanFactory是Spring的核心接口,它提供了IoC容器的基本实现。ApplicationContext是BeanFactory的一个子类,它提供了更多的企业级特性,如AOP、事件传递等等。在Spring的源码中,可以看到很多关于BeanFactory和ApplicationContext的实现,特别是在Bean的生命周期、依赖注入等方面,Spring的源码展示了很多实现细节。 此外,在Spring的源码中,还有很多关于AOP的实现,如代理模式、动态代理、CGLIB等等。这些实现使得Spring能够很好地支持AOP的实现,从而实现了很多企业级应用的需求。 总之,Spring的源码分析可以让我们更好地了解Spring的实现细节,并且对于我们学习和使用Spring也有很大的帮助。 2. Hibernate源码分析 Hibernate是一个Java持久化框架,它提供了对象/关系映射和查询语言等功能。在Hibernate源码中,可以看到很多关于ORM的实现,如映射文件、Session、Transaction等等。 Hibernate的核心接口是SessionFactory和Session,它们是Hibernate的核心实现。在Hibernate源码中,可以看到很多关于Session和Transaction的实现,如缓存机制、事务管理等等。此外,在Hibernate源码中,还有很多关于查询语言的实现,如HQL、Criteria等等。 总之,Hibernate源码分析可以让我们更好地了解Hibernate的实现细节,并且对于我们学习和使用Hibernate也有很大的帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值