spring 自动注入Hibernate中的SessionFactory 探索

来源:互联网 发布:linux中help的用法 编辑:程序博客网 时间:2024/05/18 00:32

之前用Spring的注解模式配置Hibernate的时候觉得很简单。

使用@autowire 自动注入

 @Autowired private SessionFactory sessionFactory;

然后在方法中直接使用

Session session = sessionFactory.getCurrentSession()

但是,后来看源码的时候却有了疑问。

在XML配置文件中, bean 的配置里面 SessionFactory 映射的 类文件是org.springframework.orm.hibernate4.LocalSessionFactoryBean

<bean id="sessionFactory"  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

然而打开 LocalSessionFactoryBean 类中的代码,却没有发现getCurrentSession()这个方法。

后来查询资料才发现真正的原因。

LocalSessionFactoryBean 实现了 接口 FactoryBean,FactoryBean中有一个方法 : getObject()

根据Bean的Id, 从BeanFactory中获取的实际上是FactoryBeangetObject()返回的对象,而不是FactoryBean本身。

LocalSessionFactoryBean中我们看到getObject()方法的具体实现如下:

    @Override    public SessionFactory getObject() {        return this.sessionFactory;    }

它直接返回了一个sessionFactory对象。
现在问题又来了,sessionFactory实际上也是一个接口,那么它的具体实现是在什么地方呢?

我们又看到 LocalSessionFactoryBean 还实现了另外一个接口InitializingBean,顾名思义,这个接口就是提供获得Bean时候的初始化操作用的。

这个接口只定义了一个方法:

public interface InitializingBean {    void afterPropertiesSet() throws Exception;}

LocalSessionFactoryBean 对这个方法的具体实现有很多代码,我只截取最关键的代码如下:

        // Build SessionFactory instance.        this.configuration = sfb;        this.sessionFactory = buildSessionFactory(sfb);

可见 sessionFactory成员的装配,是因为使用了buildSessionFactory(sfb)方法。

这个sfb 变量是什么呢?

LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver);

可以看到sfb读取了数据库的配置信息

buildSessionFactory方法做了什么事情呢?

这个方法下面有多层封装,层层往下,最关键的代码是···Configuration中的···buildSessionFactory()方法,其具体代码如下:

    public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {        LOG.debugf("Preparing to build session factory with filters : %s", this.filterDefinitions);        this.buildTypeRegistrations(serviceRegistry);        this.secondPassCompile();        if(!this.metadataSourceQueue.isEmpty()) {            LOG.incompleteMappingMetadataCacheProcessing();        }        this.validate();        Environment.verifyProperties(this.properties);        Properties copy = new Properties();        copy.putAll(this.properties);        ConfigurationHelper.resolvePlaceHolders(copy);        Settings settings = this.buildSettings(copy, serviceRegistry);        return new SessionFactoryImpl(this, this.mapping, serviceRegistry, settings, this.sessionFactoryObserver);    }

可以看到,在这个代码中,最后的 new SessionFactoryImpl...才是SessionFactory接口的真正实现。

最后的真正实现getCurrentSession()的代码如下:

    public Session getCurrentSession() throws HibernateException {        if(this.currentSessionContext == null) {            throw new HibernateException("No CurrentSessionContext configured!");        } else {            return this.currentSessionContext.currentSession();        }    }
0 0
原创粉丝点击