spring SqlSessionFactoryBean创建SqlSessionFactory
2015-11-03 17:42
483 查看
Application.xml
为什么返回的是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()。
<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
ApplicationContext 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()。
public Object getBean(String name) throws BeansException { return getBeanFactory().getBean(name); }2、调用AbstractRefreshableApplicationContext的getBeanFactory()返回ConfigurableListableBeanFactory接口实现类DefaultListableBeanFactory
@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()
public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }4、调用AbstractBeanFactory的doGetBean()
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接口,若未实现则返回上一步创建的单例
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; }
相关文章推荐
- java运行
- java类Writer和类Reader小结
- java进阶(四)------java编程规范---代码质量检测工具FindBugs、PMD和CheckStyle的安装
- java进阶(四)------java编程规范---代码质量检测工具FindBugs、PMD和CheckStyle的安装
- eclipse maven创建工程缺少目录的解决办法
- Java基础:集合
- 安装Maven后提示找不到JDK的错误 。The Maven Integration requires that Eclipse be running in a JDK
- Java并发编程 之 线程池核心ThreadPoolExecutor
- spring4 maven3 mybatis
- struts2 数据传输问题---“POST方式提交数据量过大,在后台接收不到数据”问题的解决
- java 自带的消息队列
- Java类中继承与初始化
- spring 的配置详解
- java各种类型转化的转载集合 慢慢添加
- Elasticsearch - Java API(与集群交互)
- SpringMVC单文件上传、多文件上传、文件列表显示、文件下载
- 17-MyEclipse快速定位文件的方法
- Java 反转单向链表
- Java Web应用中的任务调度
- 从”JAVA“而终 N/:易混淆知识点大全