美文网首页
spring 自动注入Hibernate中的SessionFac

spring 自动注入Hibernate中的SessionFac

作者: self_vc | 来源:发表于2017-04-01 15:05 被阅读0次

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

    相关文章

      网友评论

          本文标题:spring 自动注入Hibernate中的SessionFac

          本文链接:https://www.haomeiwen.com/subject/rxpiottx.html