之前用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();
}
}
```