spring SqlSessionFactoryBean创建SqlSessionFactory

来源:互联网 发布:linux中chmod -r 777 编辑:程序博客网 时间:2024/05/17 23:53
Application.xml
<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;}

原创粉丝点击