`

spring 集成 hiberntae 之LocalSessionFactoryBean介绍

 
阅读更多
 

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来初始化了整个加载过程就是这样子。

 

        

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics