1:定义
LocalSessionFactoryBean 类主要作用是把hibernate的SessionFactory纳入到spring的容器中,由spring来管理SessionFactory,我们也可以依赖注入sessionFactory。
2:继承关系
LocalSessionFactoryBean 继承了HibernateExceptionTranslator类,实现了FactoryBean<SessionFactory>, ResourceLoaderAware, InitializingBean, DisposableBean类。
- HibernateExceptionTranslator:负责转换hibernate异常(HibernateException)为spring异常体系(DataAccessException )
- FactoryBean:对普通的spring bean进行封装,类中getObject方法是返回被封装的bean。
- ResourceLoaderAware:当实现了
ResourceLoaderAware
接口的类部署到application context(比如受Spring管理的bean)中时,它会被application context识别为ResourceLoaderAware
。 接着application context会调用setResourceLoader(ResourceLoader)
方法,并把自身作为参数传入该方法(记住,所有Spring里的application context都实现了ResourceLoader
接口)。 - InitializingBean:实现该接口的bean,spring会在初始化bean时调用InitializingBean接口里的afterPropertiesSet方法。
- DisposableBean:在bean被销毁时调用destroy方法
3:功能
既然LocalSessionFactoryBean 类主要作用是把hibernate的SessionFactory纳入到spring的容器中,那么hibernate的SessionFactory肯定也在这个类中初始化那么在哪初始化呢,上面讲到LocalSessionFactoryBean 实现 了InitializingBean接口,spring初始化这个bean时调用了afterPropertiesSet方法
下面是源代码afterPropertiesSet的实现:
public void afterPropertiesSet() throws IOException { LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver); if (this.configLocations != null) { for (Resource resource : this.configLocations) { // Load Hibernate configuration from given location. sfb.configure(resource.getURL()); } } if (this.mappingResources != null) { // Register given Hibernate mapping definitions, contained in resource files. for (String mapping : this.mappingResources) { Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader()); sfb.addInputStream(mr.getInputStream()); } } if (this.mappingLocations != null) { // Register given Hibernate mapping definitions, contained in resource files. for (Resource resource : this.mappingLocations) { sfb.addInputStream(resource.getInputStream()); } } if (this.cacheableMappingLocations != null) { // Register given cacheable Hibernate mapping definitions, read from the file system. for (Resource resource : this.cacheableMappingLocations) { sfb.addCacheableFile(resource.getFile()); } } if (this.mappingJarLocations != null) { // Register given Hibernate mapping definitions, contained in jar files. for (Resource resource : this.mappingJarLocations) { sfb.addJar(resource.getFile()); } } if (this.mappingDirectoryLocations != null) { // Register all Hibernate mapping definitions in the given directories. for (Resource resource : this.mappingDirectoryLocations) { File file = resource.getFile(); if (!file.isDirectory()) { throw new IllegalArgumentException( "Mapping directory location [" + resource + "] does not denote a directory"); } sfb.addDirectory(file); } } if (this.entityInterceptor != null) { sfb.setInterceptor(this.entityInterceptor); } if (this.namingStrategy != null) { sfb.setNamingStrategy(this.namingStrategy); } if (this.hibernateProperties != null) { sfb.addProperties(this.hibernateProperties); } if (this.annotatedClasses != null) { sfb.addAnnotatedClasses(this.annotatedClasses); } if (this.annotatedPackages != null) { sfb.addPackages(this.annotatedPackages); } if (this.packagesToScan != null) { sfb.scanPackages(this.packagesToScan); } if (this.jtaTransactionManager != null) { sfb.setJtaTransactionManager(this.jtaTransactionManager); } // Build SessionFactory instance. this.configuration = sfb; this.sessionFactory = buildSessionFactory(sfb); }
方法一开始就新建了LocalSessionFactoryBuilder对象,这个对象一看名字就知道就是生成SessionFactory用的,他直接继承了hibernate的Configuration类,在hibernate中Configuration就是来生成SessionFactory的,中间代码都是在配置环境,hibernate配置文件路径,注解类路径等等,最后调用了buildSessionFactory(sfb);方法,其实这个方法里面就是调用了sfb.buildSessionFactory();那为什么不直接调用呢反而多此一举的感觉,其实这个方法目的就是留个口子,用户可以覆盖此方法定制自己的SessionFactory初始化。继续看sfb.buildSessionFactory()方法,
public SessionFactory buildSessionFactory() throws HibernateException { ClassLoader appClassLoader = (ClassLoader) getProperties().get(AvailableSettings.APP_CLASSLOADER); Thread currentThread = Thread.currentThread(); ClassLoader threadContextClassLoader = currentThread.getContextClassLoader(); boolean overrideClassLoader = (appClassLoader != null && !appClassLoader.equals(threadContextClassLoader)); if (overrideClassLoader) { currentThread.setContextClassLoader(appClassLoader); } try { return super.buildSessionFactory(); } finally { if (overrideClassLoader) { currentThread.setContextClassLoader(threadContextClassLoader); } } }
开始做了一些出来确保当前类加载器就是应用类加载器,然后调用了super.buildSessionFactory();方法,开始说过LocalSessionFactoryBuilder是继承Configuration的,现在它直接调用了父类的buildSessionFactory()也就是交给hibernate的Configuration来初始化了整个加载过程就是这样子。
相关推荐
Class'org.springframework.orm.hibernate3.LocalSessionFactoryBean'not found 解决办法
spring整合hibernate过程中,spring中使用的.jar必备包。LocalSessionFactoryBean等类的都可在包中引用
spring-hibernate3.jar包,直接导入路径即可,解决Class 'org.springframework.orm.hibernate3.LocalSessionFactoryBean' not found这个错误
LocalSessionFactoryBean LocalSlsbInvokerInterceptor LocalStatelessSessionBeanDefinitionParser LocalStatelessSessionProxyFactoryBean LocalTaskExecutorThreadPool LocalTransactionManagerLookup ...
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <value>com/bean/Tuser.hbm.xml</value> org.hibernate.dialect.OracleDialect ...
--此处hibernate 的映射采用的是.xml 配置则应设置为:class=”org.springframework.orm.hibernate3.LocalSessionFactoryBean”--> <property name="dataSource" ref="dataSource" /> ...
配置org.apache.commons.dbcp.BasicDataSource, spring要整合hibernate,需要用到一个关键类LocalSessionFactoryBean.配置如下
第3~9行定义了一个数据源,其实现类是apache的BasicDataSource,第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值...
spring和hibernate需要的jar,直接导入项目中就可以,解决Class 'org.springframework.orm.hibernate3.LocalSessionFactoryBean' not found和BasicDataSource not found错误