spring 自動注入Hibernate中的SessionFactory 探索

之前用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```中獲取的實際上是```FactoryBean```的```getObject()```返回的對象,而不是```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();
        }
    }
```




最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容