您的位置:首页 > 编程语言 > Java开发

spring SqlSessionFactoryBean创建SqlSessionFactory

2018-02-25 14:57 981 查看
原文地址:http://blog.csdn.net/wdyr321/article/details/11763979
Application.xml
[xml] view plain copy<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  <property name="dataSource" ref="dataSource" />  
  <property name="configLocation" value="classpath:SQL_MAP_SERVICE_CONFIG.xml" />  
</bean>  
创建SqlSessionFactory[java] view plain copyApplicationContext ctx = new ClassPathXmlApplicationContext("APPLICATION.xml");  
SqlSessionFactory sqlSessionFactory=(SqlSessionFactory) ctx.getBean("sqlSessionFactory");  
为什么返回的是SqlSessionFactory对象而不是SqlSessionFactoryBean
首先spring在初始化的时候会将所有创建的单例以Map<K,V>的形式放入singletonObjects,同时调用FactoryBean的getObject()将返回的对象以Map<K,V>的形式放入factoryBeanObjectCache如{sqlSessionFactory=org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@d997f9}
然后getBean的时候,spring利用getSingleton从singletonObjects获取单例(这里是SqlSessionFactoryBean对象),判断是否实现了FactoryBean接口,若实现了就从factoryBeanObjectCache利用beanname(这里是sqlSessionFactory)重新获取,若未实现则返回getSingleton获取的单例初始化的源码有些复杂,理不清,下面仅仅是getBean的源码:1、首先调用的是ClassPathXmlApplicationContext父类AbstractRefreshableApplicationContext的父类AbstractApplicationContext的getBean()。[java] view plain copypublic Object getBean(String name) throws BeansException {  
    return getBeanFactory().getBean(name);  
}  
2、调用AbstractRefreshableApplicationContext的getBeanFactory()返回ConfigurableListableBeanFactory接口实现类DefaultListableBeanFactory[java] view plain copy      
@Override(重写了AbstractApplicationContext的getBeanFactory抽象方法)  
    public final ConfigurableListableBeanFactory getBeanFactory() {  
        synchronized (this.beanFactoryMonitor) {  
            if (this.beanFactory == null) {  
                throw new IllegalStateException("BeanFactory not initialized or already closed - " +  
                        "call 'refresh' before accessing beans via the ApplicationContext");  
            }  
            return this.beanFactory;  
        }  
    }  
3、调用DefaultListableBeanFactory的父类AbstractBeanFactory的geBean()[java] view plain copy      
public Object getBean(String name) throws BeansException {  
        return doGetBean(name, null, null, false);  
    }  
4、调用AbstractBeanFactory的doGetBean()[java] view plain copy      
protected  T doGetBean(  
            final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)  
            throws BeansException {  
  
        final String beanName = transformedBeanName(name);  
        Object bean;  
  
        // Eagerly check singleton cache for manually registered singletons.  
        Object sharedInstance = getSingleton(beanName);//根据bean路径获取单例  
        if (sharedInstance != null && args == null) {  
            if (logger.isDebugEnabled()) {  
                if (isSingletonCurrentlyInCreation(beanName)) {  
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
                            "' that is not fully initialized yet - a consequence of a circular reference");  
                }  
                else {  
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
                }  
            }  
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
        }  
5、调用AbstractBeanFactory的getObjectForBeanInstance(),判断是否实现FactoryBean接口,若未实现则返回上一步创建的单例[java] view plain copy      
protected Object getObjectForBeanInstance(  
            Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {  
  
        // Don't let calling code try to dereference the factory if the bean isn't a factory.  
        if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {  
            throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());  
        }  
  
        // Now we have the bean instance, which may be a normal bean or a FactoryBean.  
        // If it's a FactoryBean, we use it to create a bean instance, unless the  
        // caller actually wants a reference to the factory.  
        if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {  
            return beanInstance;  
        }//判断是否实现FactoryBean接口  
  
        Object object = null;  
        if (mbd == null) {  
            object = getCachedObjectForFactoryBean(beanName);//从factoryBeanObjectCache中取出FactoryBean创建的对象  
        }  
        if (object == null) {  
            // Return bean instance from factory.  
            FactoryBean factory = (FactoryBean) beanInstance;  
            // Caches object obtained from FactoryBean if it is a singleton.  
            if (mbd == null && containsBeanDefinition(beanName)) {  
                mbd = getMergedLocalBeanDefinition(beanName);  
            }  
            boolean synthetic = (mbd != null && mbd.isSynthetic());  
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);  
        }  
        return object;  
    }  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  SqlSessionFactoryBean