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