2、Spring的LocalSessionFactoryBean创建过程源码分析

spring的LocalSessionFactoryBean生成过程与hibernate的SessionFactory生成过程是高度吻合的

为了后面源码分析,首先讲解一个接口,一个类的功能:
①、接口InitializingBean
接口的功能:这个接口专门为bean设计的,它只有一个方法。我们知道所有的bean都是由beanFactory来生成的,如果一个bean实现了该接口,在beanFactory为该bean装配好了所有的属性以后,在返回实际bean之前还会调用一次该接口的afterPropertiesSet(...)方法。其设计目的是为了实现个性化,或者是为了检查bean属性值的完整性等。

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

②、类LocalSessionFactoryBuilder

显然,LocalSessionFactoryBuilder继承自org.hibernate.cfg.Configuration,那么Configuration拥有的属性,LocalSessionFactoryBuilder也具有

public class LocalSessionFactoryBuilder extends Configuration{
    //...
}

从LocalSessionFactoryBean源码中分析出其于hibernate的sessionFactory和configuration之间的关系:

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

//②、类LocalSessionFactoryBuilder
//显然,LocalSessionFactoryBuilder继承自org.hibernate.cfg.Configuration,那么Configuration拥有的属性,LocalSessionFactoryBuilder也具有
public class LocalSessionFactoryBuilder extends Configuration{
    //...
}

//现在主要分析LocalSessionFactoryBean
//1、看一下几个非常重要的属性值定义
public class LocalSessionFactoryBean extends... implements InitializingBean, ...{
    //数据源
    private DataSource dataSource;
    //hibernate的配置文件Xxx.cfg.xml所在的
    //位置多个可以用","隔开
    private Resource[] configLocations;
    private String[] mappingResources;
    //hibernate的映射文件位置
    private Resource[] mappingLocations;
    //hibernate的properties属性,存放了配置
    //文件中解析property标签的结果
    private Properties hibernateProperties;
    //hibernate的configuration属性
    private Configuration configuration;
    //这个sessionfactory是hibernate的sessionFactory
    private SessionFactory sessionFactory;

    //省略其它的属性以及setter方法...

    //注意这个set方法,说明当只有一个配置文件
    //的时候可以使用configLocation属性来配置,
    //最终也会被转换成configLocations
    public void setConfigLocation(Resource configLocation) {
        this.configLocations = new Resource[] {configLocation};
    }

    @Override
    public void afterPropertiesSet() throws IOException {
        LocalSessionFactoryBuilder sfb = new LocalSessionFactoryBuilder(this.dataSource, this.resourcePatternResolver);

        if (this.configLocations != null) {
            for (Resource resource : this.configLocations) {
                //sfb.configure(...)实际上也就是调用其父类
                //org.hibernate.cfg.Configuration的configure(...)方法
                //这里完成xxx.cfg.xml文件中property节点
                //的解析,得到一个properties
                sfb.configure(resource.getURL());
            }
        }

        //mappingResources和mappingLocations效果是一样的,
        //都会将资源转换成输入流,并调用sfb.addInputStream(...)方法
        //sfb.addInputStream(...)最终会完成xxx.cfg.xml文件的
        //非property节点解析(主要有3类:mapping、class-cache和collection-cache)
        //将解析结果放入到metadataSourceQueue中
        if (this.mappingResources != null) {
            for (String mapping : this.mappingResources) {
                Resource mr = new ClassPathResource(mapping.trim(), this.resourcePatternResolver.getClassLoader());
                sfb.addInputStream(mr.getInputStream());
            }
        }
        if (this.mappingLocations != null) {
            for (Resource resource : this.mappingLocations) {
                sfb.addInputStream(resource.getInputStream());
            }
        }

        //sfb.addProperties(...)方法会调用properties.putAll( extraProperties )方法
        //说明我们可以配置一个properties对象来达到配置xxx.cfg.xml相同的效果!!
        //两方面的配置最终都会放入到properties对象中
        if (this.hibernateProperties != null) {
            sfb.addProperties(this.hibernateProperties);
        }

        //省略若干其它方法...

        // 将sfb向上转型,LocalSessionFactoryBean中的configuration属性实际上
        // 就是org.hibernate.cfg.Configuration
        this.configuration = sfb;
        //在得到configuration以后,通过它来创建一个sessionFactory,
        //并赋值给sessionFactory属性(LocalSessionFactoryBean的属性)
        //在底层会调用return super.buildSessionFactory()来的到一个
        //sessionFactory,由于其父类是org.hibernate.cfg.Configuration
        //所以,相当于调用了configuration.buildSessionFactory()来生成
        //sessionFactory,这是hibernate4.0版本之前的做法,新版本已经
        //被buildSessionFactory(ServiceRegistry)所取代。
        this.sessionFactory = buildSessionFactory(sfb);
    }
}

总结spring的LocalSessionFactoryBean实际完成的工作有:
1、通过解析bean中的configLocation和mappingLocations等属性,得到一个hibernate的原生态的org.hibernate.cfg.Configuration属性
2、通过org.hibernate.cfg.Configuration生成一个hibernate原生态的org.hibernate.SessionFactory属性
3、可以在外部配置一个Properties对象,并将其配置为properties属性,可以达到与xxx.cfg.xml相同的配置效果

时间: 2024-10-10 03:28:37

2、Spring的LocalSessionFactoryBean创建过程源码分析的相关文章

linux内核中socket的创建过程源码分析(总结性质)

http://www.jianshu.com/p/5d82a685b5b6 在漫长地分析完socket的创建源码后,发现一片浆糊,所以特此总结,我的博客中同时有另外一篇详细的源码分析,内核版本为3.9,建议在阅读本文后若还有兴趣再去看另外一篇博文.绝对不要单独看另外一篇. 一:调用链: 二:数据结构 一一看一下每个数据结构的意义: 1) socket, sock, inet_sock, tcp_sock的关系创建完sk变量后,回到inet_create函数中: 这里是根据sk变量得到inet_s

spring启动加载过程源码分析

我们知道启动spring容器两常见的两种方式(其实都是加载spring容器的xml配置文件时启动的): 1.在应用程序下加载 ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-context.xml"); 2.web模式下加载 <context-param> <param-name>contextConfigLocation</param-name> <par

linux内核中socket的创建过程源码分析(详细分析)

http://www.cnblogs.com/hyd-desert-camel/p/3536341.html 1三个相关数据结构. 关于socket的创建,首先需要分析socket这个结构体,这是整个的核心. 104 struct socket { 105         socket_state            state; 106 107         kmemcheck_bitfield_begin(type); 108         short                 

Flume-NG启动过程源码分析(三)(原创)

上一篇文章分析了Flume如何加载配置文件的,动态加载也只是重复运行getConfiguration(). 本篇分析加载配置文件后各个组件是如何运行的? 加载完配置文件订阅者Application类会收到订阅信息执行: @Subscribe public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) { stopAllComponents(); startAllComponents(conf)

【Java】【Flume】Flume-NG启动过程源码分析(一)

从bin/flume 这个shell脚本可以看到Flume的起始于org.apache.flume.node.Application类,这是flume的main函数所在. main方法首先会先解析shell命令,如果指定的配置文件不存在就甩出异常. 根据命令中含有"no-reload-conf"参数,决定采用那种加载配置文件方式:一.没有此参数,会动态加载配置文件,默认每30秒加载一次配置文件,因此可以动态修改配置文件:二.有此参数,则只在启动时加载一次配置文件.实现动态加载功能采用了

【Java】【Flume】Flume-NG启动过程源码分析(二)

本节分析配置文件的解析,即PollingPropertiesFileConfigurationProvider.FileWatcherRunnable.run中的eventBus.post(getConfiguration()).分析getConfiguration()方法.此方法在AbstractConfigurationProvider类中实现了,并且这个类也初始化了三大组件的工厂类:this.sourceFactory = new DefaultSourceFactory();this.s

【Java】【Flume】Flume-NG启动过程源码分析(三)

本篇分析加载配置文件后各个组件是如何运行的? 加载完配置文件订阅者Application类会收到订阅信息执行: @Subscribe public synchronized void handleConfigurationEvent(MaterializedConfiguration conf) { stopAllComponents(); startAllComponents(conf); } MaterializedConfiguration conf就是getConfiguration()

Spring Boot 揭秘与实战 源码分析 - 开箱即用,内藏玄机

文章目录 1. 开箱即用,内藏玄机 2. 总结 3. 源代码 Spring Boot提供了很多"开箱即用"的依赖模块,那么,Spring Boot 如何巧妙的做到开箱即用,自动配置的呢? 开箱即用,内藏玄机 Spring Boot提供了很多"开箱即用"的依赖模块,都是以spring-boot-starter-xx作为命名的.例如,之前提到的 spring-boot-starter-redis.spring-boot-starter-data-mongodb.spri

配置一个逻辑CPU专用于实时任务----Kithara RTS工程源码分析

本文以windows实时拓展Kithara RTS安装目录下的smp文件夹内的DedicatedRealTimeTask项目为例,讲解使实时任务以独占一个逻辑CPU的方式运行,并实现任务间的同步. 目前多核计算机已经普及,多数的PC都是多核的.针对这种多核结构,我们设想把计算机划分为不同的硬件区间,其中一部分用于被实时任务专用,另一部分是被windows使用的,两者之间互不干扰,这样实时任务可以实现更好的实时性能.这种硬件划分,一般是按照物理CPU的核心数,即逻辑CPU的数量来配置的.可以配置一