原文地址:http://blog.youkuaiyun.com/wdyr321/article/details/11763979
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>
- 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);
- }
- @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;
- }
- }
- public Object getBean(String name) throws BeansException {
- return doGetBean(name, null, null, false);
- }
- 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);
- }
- 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;
- }