Spring源代码解析(八):Spring驱动Hibernate的实现

O/R工具出现之后,简化了许多复杂的信息持久化的开发。Spring应用开发者可以通过Spring提供的O/R方案更方便的使用各种持久化工具,比如Hibernate;下面我们就Spring+Hibernate中的Spring实现做一个简单的剖析。
Spring对Hinberanate的配置是通过LocalSessionFactoryBean来完成的,这是一个工厂Bean的实现,在基类AbstractSessionFactoryBean中:

Java代码 复制代码
  1. /**  
  2.  * 这是FactoryBean需要实现的接口方法,直接取得当前的sessionFactory的值  
  3.  */  
  4. public Object getObject() {   
  5.     return this.sessionFactory;   
  6. }  
    /**
     * 这是FactoryBean需要实现的接口方法,直接取得当前的sessionFactory的值
     */
    public Object getObject() {
        return this.sessionFactory;
    }


这个值在afterPropertySet中定义:

Java代码 复制代码
  1. public void afterPropertiesSet() throws Exception {   
  2.     //这个buildSessionFactory是通过配置信息得到SessionFactory的地方   
  3.     SessionFactory rawSf = buildSessionFactory();   
  4.     //这里使用了Proxy方法插入对getCurrentSession的拦截,得到和事务相关的session   
  5.     this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);   
  6. }  
    public void afterPropertiesSet() throws Exception {
        //这个buildSessionFactory是通过配置信息得到SessionFactory的地方
        SessionFactory rawSf = buildSessionFactory();
        //这里使用了Proxy方法插入对getCurrentSession的拦截,得到和事务相关的session
        this.sessionFactory = wrapSessionFactoryIfNecessary(rawSf);
    }


我们先看看SessionFactory是怎样创建的,这个方法很长,包含了创建Hibernate的SessionFactory的详尽步骤:

Java代码 复制代码
  1. protected SessionFactory buildSessionFactory() throws Exception {   
  2.     SessionFactory sf = null;   
  3.   
  4.     // Create Configuration instance.   
  5.     Configuration config = newConfiguration();   
  6.   
  7.     //这里配置数据源,事务管理器,LobHander到Holder中,这个Holder是一个ThreadLocal变量,这样这些资源就和线程绑定了   
  8.     if (this.dataSource != null) {   
  9.         // Make given DataSource available for SessionFactory configuration.   
  10.         configTimeDataSourceHolder.set(this.dataSource);   
  11.     }   
  12.   
  13.     if (this.jtaTransactionManager != null) {   
  14.         // Make Spring-provided JTA TransactionManager available.   
  15.         configTimeTransactionManagerHolder.set(this.jtaTransactionManager);   
  16.     }   
  17.   
  18.     if (this.lobHandler != null) {   
  19.         // Make given LobHandler available for SessionFactory configuration.   
  20.         // Do early because because mapping resource might refer to custom types.   
  21.         configTimeLobHandlerHolder.set(this.lobHandler);   
  22.     }   
  23.   
  24.     //这里是使用Hibernate的各个属性的配置,这里使用了Configuration类来抽象这些数据   
  25.     try {   
  26.         // Set connection release mode "on_close" as default.   
  27.         // This was the case for Hibernate 3.0; Hibernate 3.1 changed   
  28.         // it to "auto" (i.e. "after_statement" or "after_transaction").   
  29.         // However, for Spring's resource management (in particular for   
  30.         // HibernateTransactionManager), "on_close" is the better default.   
  31.         config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());   
  32.   
  33.         if (!isExposeTransactionAwareSessionFactory()) {   
  34.             // Not exposing a SessionFactory proxy with transaction-aware   
  35.             // getCurrentSession() method -> set Hibernate 3.1 CurrentSessionContext   
  36.             // implementation instead, providing the Spring-managed Session that way.   
  37.             // Can be overridden by a custom value for corresponding Hibernate property.   
  38.             config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS,   
  39.                     "org.springframework.orm.hibernate3.SpringSessionContext");   
  40.         }   
  41.   
  42.         if (this.entityInterceptor != null) {   
  43.             // Set given entity interceptor at SessionFactory level.   
  44.             config.setInterceptor(this.entityInterceptor);   
  45.         }   
  46.   
  47.         if (this.namingStrategy != null) {   
  48.             // Pass given naming strategy to Hibernate Configuration.   
  49.             config.setNamingStrategy(this.namingStrategy);   
  50.         }   
  51.   
  52.         if (this.typeDefinitions != null) {   
  53.             // Register specified Hibernate type definitions.   
  54.             Mappings mappings = config.createMappings();   
  55.             for (int i = 0; i < this.typeDefinitions.length; i++) {   
  56.                 TypeDefinitionBean typeDef = this.typeDefinitions[i];   
  57.                 mappings.addTypeDef(typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters());   
  58.             }   
  59.         }   
  60.   
  61.         if (this.filterDefinitions != null) {   
  62.             // Register specified Hibernate FilterDefinitions.   
  63.             for (int i = 0; i < this.filterDefinitions.length; i++) {   
  64.                 config.addFilterDefinition(this.filterDefinitions[i]);   
  65.             }   
  66.         }   
  67.   
  68.         if (this.configLocations != null) {   
  69.             for (int i = 0; i < this.configLocations.length; i++) {   
  70.                 // Load Hibernate configuration from given location.   
  71.                 config.configure(this.configLocations[i].getURL());   
  72.             }   
  73.         }   
  74.   
  75.         if (this.hibernateProperties != null) {   
  76.             // Add given Hibernate properties to Configuration.   
  77.             config.addProperties(this.hibernateProperties);   
  78.         }   
  79.   
  80.         if (this.dataSource != null) {   
  81.             boolean actuallyTransactionAware =   
  82.                     (this.useTransactionAwareDataSource || this.dataSource instanceof TransactionAwareDataSourceProxy);   
  83.             // Set Spring-provided DataSource as Hibernate ConnectionProvider.   
  84.             config.setProperty(Environment.CONNECTION_PROVIDER,   
  85.                     actuallyTransactionAware ?   
  86.                     TransactionAwareDataSourceConnectionProvider.class.getName() :   
  87.                     LocalDataSourceConnectionProvider.class.getName());   
  88.         }   
  89.   
  90.         if (this.jtaTransactionManager != null) {   
  91.             // Set Spring-provided JTA TransactionManager as Hibernate property.   
  92.             config.setProperty(   
  93.                     Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName());   
  94.         }   
  95.   
  96.         if (this.mappingLocations != null) {   
  97.             // Register given Hibernate mapping definitions, contained in resource files.   
  98.             for (int i = 0; i < this.mappingLocations.length; i++) {   
  99.                 config.addInputStream(this.mappingLocations[i].getInputStream());   
  100.             }   
  101.         }   
  102.   
  103.         if (this.cacheableMappingLocations != null) {   
  104.             // Register given cacheable Hibernate mapping definitions, read from the file system.   
  105.             for (int i = 0; i < this.cacheableMappingLocations.length; i++) {   
  106.                 config.addCacheableFile(this.cacheableMappingLocations[i].getFile());   
  107.             }   
  108.         }   
  109.   
  110.         if (this.mappingJarLocations != null) {   
  111.             // Register given Hibernate mapping definitions, contained in jar files.   
  112.             for (int i = 0; i < this.mappingJarLocations.length; i++) {   
  113.                 Resource resource = this.mappingJarLocations[i];   
  114.                 config.addJar(resource.getFile());   
  115.             }   
  116.         }   
  117.   
  118.         if (this.mappingDirectoryLocations != null) {   
  119.             // Register all Hibernate mapping definitions in the given directories.   
  120.             for (int i = 0; i < this.mappingDirectoryLocations.length; i++) {   
  121.                 File file = this.mappingDirectoryLocations[i].getFile();   
  122.                 if (!file.isDirectory()) {   
  123.                     throw new IllegalArgumentException(   
  124.                             "Mapping directory location [" + this.mappingDirectoryLocations[i] +   
  125.                             "] does not denote a directory");   
  126.                 }   
  127.                 config.addDirectory(file);   
  128.             }   
  129.         }   
  130.   
  131.         if (this.entityCacheStrategies != null) {   
  132.             // Register cache strategies for mapped entities.   
  133.             for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) {   
  134.                 String className = (String) classNames.nextElement();   
  135.                 String[] strategyAndRegion =   
  136.                         StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className));   
  137.                 if (strategyAndRegion.length > 1) {   
  138.                     config.setCacheConcurrencyStrategy(className, strategyAndRegion[0], strategyAndRegion[1]);   
  139.                 }   
  140.                 else if (strategyAndRegion.length > 0) {   
  141.                     config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]);   
  142.                 }   
  143.             }   
  144.         }   
  145.   
  146.         if (this.collectionCacheStrategies != null) {   
  147.             // Register cache strategies for mapped collections.   
  148.             for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) {   
  149.                 String collRole = (String) collRoles.nextElement();   
  150.                 String[] strategyAndRegion =   
  151.                         StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole));   
  152.                 if (strategyAndRegion.length > 1) {   
  153.                     config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]);   
  154.                 }   
  155.                 else if (strategyAndRegion.length > 0) {   
  156.                     config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]);   
  157.                 }   
  158.             }   
  159.         }   
  160.   
  161.         if (this.eventListeners != null) {   
  162.             // Register specified Hibernate event listeners.   
  163.             for (Iterator it = this.eventListeners.entrySet().iterator(); it.hasNext();) {   
  164.                 Map.Entry entry = (Map.Entry) it.next();   
  165.                 Assert.isTrue(entry.getKey() instanceof String, "Event listener key needs to be of type String");   
  166.                 String listenerType = (String) entry.getKey();   
  167.                 Object listenerObject = entry.getValue();   
  168.                 if (listenerObject instanceof Collection) {   
  169.                     Collection listeners = (Collection) listenerObject;   
  170.                     EventListeners listenerRegistry = config.getEventListeners();   
  171.                     Object[] listenerArray =   
  172.                             (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size());   
  173.                     listenerArray = listeners.toArray(listenerArray);   
  174.                     config.setListeners(listenerType, listenerArray);   
  175.                 }   
  176.                 else {   
  177.                     config.setListener(listenerType, listenerObject);   
  178.                 }   
  179.             }   
  180.         }   
  181.   
  182.         // Perform custom post-processing in subclasses.   
  183.         postProcessConfiguration(config);   
  184.   
  185.         // 这里是根据Configuration配置创建SessionFactory的地方   
  186.         logger.info("Building new Hibernate SessionFactory");   
  187.         this.configuration = config;   
  188.         sf = newSessionFactory(config);   
  189.     }   
  190.     //最后把和线程绑定的资源清空   
  191.     finally {   
  192.         if (this.dataSource != null) {   
  193.             // Reset DataSource holder.   
  194.             configTimeDataSourceHolder.set(null);   
  195.         }   
  196.   
  197.         if (this.jtaTransactionManager != null) {   
  198.             // Reset TransactionManager holder.   
  199.             configTimeTransactionManagerHolder.set(null);   
  200.         }   
  201.   
  202.         if (this.lobHandler != null) {   
  203.             // Reset LobHandler holder.   
  204.             configTimeLobHandlerHolder.set(null);   
  205.         }   
  206.     }   
  207.   
  208.     // Execute schema update if requested.   
  209.     if (this.schemaUpdate) {   
  210.         updateDatabaseSchema();   
  211.     }   
  212.   
  213.     return sf;   
  214. }  
    protected SessionFactory buildSessionFactory() throws Exception {
        SessionFactory sf = null;

        // Create Configuration instance.
        Configuration config = newConfiguration();

        //这里配置数据源,事务管理器,LobHander到Holder中,这个Holder是一个ThreadLocal变量,这样这些资源就和线程绑定了
        if (this.dataSource != null) {
            // Make given DataSource available for SessionFactory configuration.
            configTimeDataSourceHolder.set(this.dataSource);
        }

        if (this.jtaTransactionManager != null) {
            // Make Spring-provided JTA TransactionManager available.
            configTimeTransactionManagerHolder.set(this.jtaTransactionManager);
        }

        if (this.lobHandler != null) {
            // Make given LobHandler available for SessionFactory configuration.
            // Do early because because mapping resource might refer to custom types.
            configTimeLobHandlerHolder.set(this.lobHandler);
        }

        //这里是使用Hibernate的各个属性的配置,这里使用了Configuration类来抽象这些数据
        try {
            // Set connection release mode "on_close" as default.
            // This was the case for Hibernate 3.0; Hibernate 3.1 changed
            // it to "auto" (i.e. "after_statement" or "after_transaction").
            // However, for Spring's resource management (in particular for
            // HibernateTransactionManager), "on_close" is the better default.
            config.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString());

            if (!isExposeTransactionAwareSessionFactory()) {
                // Not exposing a SessionFactory proxy with transaction-aware
                // getCurrentSession() method -> set Hibernate 3.1 CurrentSessionContext
                // implementation instead, providing the Spring-managed Session that way.
                // Can be overridden by a custom value for corresponding Hibernate property.
                config.setProperty(Environment.CURRENT_SESSION_CONTEXT_CLASS,
                        "org.springframework.orm.hibernate3.SpringSessionContext");
            }

            if (this.entityInterceptor != null) {
                // Set given entity interceptor at SessionFactory level.
                config.setInterceptor(this.entityInterceptor);
            }

            if (this.namingStrategy != null) {
                // Pass given naming strategy to Hibernate Configuration.
                config.setNamingStrategy(this.namingStrategy);
            }

            if (this.typeDefinitions != null) {
                // Register specified Hibernate type definitions.
                Mappings mappings = config.createMappings();
                for (int i = 0; i < this.typeDefinitions.length; i++) {
                    TypeDefinitionBean typeDef = this.typeDefinitions[i];
                    mappings.addTypeDef(typeDef.getTypeName(), typeDef.getTypeClass(), typeDef.getParameters());
                }
            }

            if (this.filterDefinitions != null) {
                // Register specified Hibernate FilterDefinitions.
                for (int i = 0; i < this.filterDefinitions.length; i++) {
                    config.addFilterDefinition(this.filterDefinitions[i]);
                }
            }

            if (this.configLocations != null) {
                for (int i = 0; i < this.configLocations.length; i++) {
                    // Load Hibernate configuration from given location.
                    config.configure(this.configLocations[i].getURL());
                }
            }

            if (this.hibernateProperties != null) {
                // Add given Hibernate properties to Configuration.
                config.addProperties(this.hibernateProperties);
            }

            if (this.dataSource != null) {
                boolean actuallyTransactionAware =
                        (this.useTransactionAwareDataSource || this.dataSource instanceof TransactionAwareDataSourceProxy);
                // Set Spring-provided DataSource as Hibernate ConnectionProvider.
                config.setProperty(Environment.CONNECTION_PROVIDER,
                        actuallyTransactionAware ?
                        TransactionAwareDataSourceConnectionProvider.class.getName() :
                        LocalDataSourceConnectionProvider.class.getName());
            }

            if (this.jtaTransactionManager != null) {
                // Set Spring-provided JTA TransactionManager as Hibernate property.
                config.setProperty(
                        Environment.TRANSACTION_MANAGER_STRATEGY, LocalTransactionManagerLookup.class.getName());
            }

            if (this.mappingLocations != null) {
                // Register given Hibernate mapping definitions, contained in resource files.
                for (int i = 0; i < this.mappingLocations.length; i++) {
                    config.addInputStream(this.mappingLocations[i].getInputStream());
                }
            }

            if (this.cacheableMappingLocations != null) {
                // Register given cacheable Hibernate mapping definitions, read from the file system.
                for (int i = 0; i < this.cacheableMappingLocations.length; i++) {
                    config.addCacheableFile(this.cacheableMappingLocations[i].getFile());
                }
            }

            if (this.mappingJarLocations != null) {
                // Register given Hibernate mapping definitions, contained in jar files.
                for (int i = 0; i < this.mappingJarLocations.length; i++) {
                    Resource resource = this.mappingJarLocations[i];
                    config.addJar(resource.getFile());
                }
            }

            if (this.mappingDirectoryLocations != null) {
                // Register all Hibernate mapping definitions in the given directories.
                for (int i = 0; i < this.mappingDirectoryLocations.length; i++) {
                    File file = this.mappingDirectoryLocations[i].getFile();
                    if (!file.isDirectory()) {
                        throw new IllegalArgumentException(
                                "Mapping directory location [" + this.mappingDirectoryLocations[i] +
                                "] does not denote a directory");
                    }
                    config.addDirectory(file);
                }
            }

            if (this.entityCacheStrategies != null) {
                // Register cache strategies for mapped entities.
                for (Enumeration classNames = this.entityCacheStrategies.propertyNames(); classNames.hasMoreElements();) {
                    String className = (String) classNames.nextElement();
                    String[] strategyAndRegion =
                            StringUtils.commaDelimitedListToStringArray(this.entityCacheStrategies.getProperty(className));
                    if (strategyAndRegion.length > 1) {
                        config.setCacheConcurrencyStrategy(className, strategyAndRegion[0], strategyAndRegion[1]);
                    }
                    else if (strategyAndRegion.length > 0) {
                        config.setCacheConcurrencyStrategy(className, strategyAndRegion[0]);
                    }
                }
            }

            if (this.collectionCacheStrategies != null) {
                // Register cache strategies for mapped collections.
                for (Enumeration collRoles = this.collectionCacheStrategies.propertyNames(); collRoles.hasMoreElements();) {
                    String collRole = (String) collRoles.nextElement();
                    String[] strategyAndRegion =
                            StringUtils.commaDelimitedListToStringArray(this.collectionCacheStrategies.getProperty(collRole));
                    if (strategyAndRegion.length > 1) {
                        config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0], strategyAndRegion[1]);
                    }
                    else if (strategyAndRegion.length > 0) {
                        config.setCollectionCacheConcurrencyStrategy(collRole, strategyAndRegion[0]);
                    }
                }
            }

            if (this.eventListeners != null) {
                // Register specified Hibernate event listeners.
                for (Iterator it = this.eventListeners.entrySet().iterator(); it.hasNext();) {
                    Map.Entry entry = (Map.Entry) it.next();
                    Assert.isTrue(entry.getKey() instanceof String, "Event listener key needs to be of type String");
                    String listenerType = (String) entry.getKey();
                    Object listenerObject = entry.getValue();
                    if (listenerObject instanceof Collection) {
                        Collection listeners = (Collection) listenerObject;
                        EventListeners listenerRegistry = config.getEventListeners();
                        Object[] listenerArray =
                                (Object[]) Array.newInstance(listenerRegistry.getListenerClassFor(listenerType), listeners.size());
                        listenerArray = listeners.toArray(listenerArray);
                        config.setListeners(listenerType, listenerArray);
                    }
                    else {
                        config.setListener(listenerType, listenerObject);
                    }
                }
            }

            // Perform custom post-processing in subclasses.
            postProcessConfiguration(config);

            // 这里是根据Configuration配置创建SessionFactory的地方
            logger.info("Building new Hibernate SessionFactory");
            this.configuration = config;
            sf = newSessionFactory(config);
        }
        //最后把和线程绑定的资源清空
        finally {
            if (this.dataSource != null) {
                // Reset DataSource holder.
                configTimeDataSourceHolder.set(null);
            }

            if (this.jtaTransactionManager != null) {
                // Reset TransactionManager holder.
                configTimeTransactionManagerHolder.set(null);
            }

            if (this.lobHandler != null) {
                // Reset LobHandler holder.
                configTimeLobHandlerHolder.set(null);
            }
        }

        // Execute schema update if requested.
        if (this.schemaUpdate) {
            updateDatabaseSchema();
        }

        return sf;
    }


而直接调用org.hibernate.cfg.Configuration来得到需要的SessionFactory:

Java代码 复制代码
  1. protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {   
  2.     return config.buildSessionFactory();   
  3. }  
    protected SessionFactory newSessionFactory(Configuration config) throws HibernateException {
        return config.buildSessionFactory();
    }


所以我们这里看到LocalSessionFactory大致起到的一个读取资源配置然后生成SessionFactory的作用;当然这里在得到 SessionFactory之后,还需要对session的事务管理作一些处理 - 使用了一个Proxy模式对getCurrentSession方法进行了拦截;

Java代码 复制代码
  1. //这里先根据当前的SessionFactory的类型得到Proxy,然后插入Spring定义好的getCurrentSession拦截器   
  2.     protected SessionFactory getTransactionAwareSessionFactoryProxy(SessionFactory target) {   
  3.         Class sfInterface = SessionFactory.class;   
  4.         if (target instanceof SessionFactoryImplementor) {   
  5.             sfInterface = SessionFactoryImplementor.class;   
  6.         }   
  7.         return (SessionFactory) Proxy.newProxyInstance(sfInterface.getClassLoader(),   
  8.                 new Class[] {sfInterface}, new TransactionAwareInvocationHandler(target));   
  9.     }  
//这里先根据当前的SessionFactory的类型得到Proxy,然后插入Spring定义好的getCurrentSession拦截器
    protected SessionFactory getTransactionAwareSessionFactoryProxy(SessionFactory target) {
        Class sfInterface = SessionFactory.class;
        if (target instanceof SessionFactoryImplementor) {
            sfInterface = SessionFactoryImplementor.class;
        }
        return (SessionFactory) Proxy.newProxyInstance(sfInterface.getClassLoader(),
                new Class[] {sfInterface}, new TransactionAwareInvocationHandler(target));
    }


拦截器的实现如下:

Java代码 复制代码
  1. private static class TransactionAwareInvocationHandler implements InvocationHandler {   
  2.   
  3.     private final SessionFactory target;   
  4.   
  5.     public TransactionAwareInvocationHandler(SessionFactory target) {   
  6.         this.target = target;   
  7.     }   
  8.   
  9.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
  10.         // Invocation on SessionFactory/SessionFactoryImplementor interface coming in...   
  11.         // 这里对getCurrentSession方法进行拦截,得到一个和当前事务绑定的session交给用户   
  12.         if (method.getName().equals("getCurrentSession")) {   
  13.             // Handle getCurrentSession method: return transactional Session, if any.   
  14.             try {   
  15.                 return SessionFactoryUtils.doGetSession((SessionFactory) proxy, false);   
  16.             }   
  17.             catch (IllegalStateException ex) {   
  18.                 throw new HibernateException(ex.getMessage());   
  19.             }   
  20.         }   
  21.         else if (method.getName().equals("equals")) {   
  22.             // Only consider equal when proxies are identical.   
  23.             return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);   
  24.         }   
  25.         else if (method.getName().equals("hashCode")) {   
  26.             // Use hashCode of SessionFactory proxy.   
  27.             return new Integer(hashCode());   
  28.         }   
  29.   
  30.         // 这里是需要运行的SessionFactory的目标方法   
  31.         try {   
  32.             return method.invoke(this.target, args);   
  33.         }   
  34.         catch (InvocationTargetException ex) {   
  35.             throw ex.getTargetException();   
  36.         }   
  37.     }   
  38. }  
    private static class TransactionAwareInvocationHandler implements InvocationHandler {

        private final SessionFactory target;

        public TransactionAwareInvocationHandler(SessionFactory target) {
            this.target = target;
        }

        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // Invocation on SessionFactory/SessionFactoryImplementor interface coming in...
            // 这里对getCurrentSession方法进行拦截,得到一个和当前事务绑定的session交给用户
            if (method.getName().equals("getCurrentSession")) {
                // Handle getCurrentSession method: return transactional Session, if any.
                try {
                    return SessionFactoryUtils.doGetSession((SessionFactory) proxy, false);
                }
                catch (IllegalStateException ex) {
                    throw new HibernateException(ex.getMessage());
                }
            }
            else if (method.getName().equals("equals")) {
                // Only consider equal when proxies are identical.
                return (proxy == args[0] ? Boolean.TRUE : Boolean.FALSE);
            }
            else if (method.getName().equals("hashCode")) {
                // Use hashCode of SessionFactory proxy.
                return new Integer(hashCode());
            }

            // 这里是需要运行的SessionFactory的目标方法
            try {
                return method.invoke(this.target, args);
            }
            catch (InvocationTargetException ex) {
                throw ex.getTargetException();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值