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;
}
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;
}
相关文章推荐
- Spring-mybatis整合配置错误,显示不能创建spring配置文件中的sqlSessionFactory的Bean
- spring SqlSessionFactoryBean创建SqlSessionFactory
- spring SqlSessionFactoryBean创建SqlSessionFactory
- Spring-Mybatis --- 配置SqlSessionFactoryBean,整合Spring-Mybatis
- Spring-mybatis整合 获取properties 创建SQLSessionFactory失败
- mybatis与spring集成中SqlSessionFactory创建流程
- MyBatis-Spring 学习笔记一 SqlSessionFactoryBean以及映射器类
- MyBatis-Spring-SqlSessionFactoryBean(session工厂)
- Spring ...BeanCreationException: Error creating bean with name 'sqlSessionFactoryWrite'
- MyBatis-Spring-SqlSessionFactoryBean
- Spring mybatis源码篇章-SqlSessionFactoryBean
- spring-mybatis 之SqlSessionFactoryBean
- mybatis-spring整合总结02_SqlSessionFactoryBean
- 重构Mybatis与Spring集成的SqlSessionFactoryBean(1)
- IDEA 启动 Error creating bean with name 'sqlSessionFactory' defined in class path resource [spring-m
- spring mybatis之sqlSessionFactoryBean
- 【spring+mybatis】MyBatis-Spring-SqlSessionFactoryBean
- MyBatis -- Spring -- SqlSessionFactoryBean
- Mybatis整合Spring SqlSessionFactoryBean的属性介绍
- springMVC+mybatis 进行单元测试时 main SqlSessionFactoryBean - Parsed configuration file: 'class path resource' 无限的读取xml文件