• 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相同的配置效果

  • 相关阅读:
    rpm包方式安装oracle21c
    有限广播地址与直接广播地址
    忽略大小写查看文件夹下重复的文件方法
    No spring.config.import property has been defined 规格严格
    application.properties 转 yaml ( 在线) 规格严格
    PG快速构建海量数据方法 规格严格
    Postgresql 查看建表语句 命令 规格严格
    一文读懂PostgreSQL数据库透明数据加密 规格严格
    PG锁监控 规格严格
    Spring Cloud Config Client 规格严格
  • 原文地址:https://www.cnblogs.com/lj95801/p/5396760.html
Copyright © 2020-2023  润新知