MyBatis源码解析之——初始化细节

先说下大体思路,Spring整合Mybatis,在Spring的初始化链中主要有以下几个重要步骤:

1、obtainFreshBeanFactory方法负责解析MyBatis的服务层Bean,即:ServiceBean,因为这些ServiceBean是通过注解@Service声明的,通常会在ServiceBean中注入XxxMapper。——这是Spring的正常操作,本文就不贴代码了。

2、invokeBeanFactoryPostProcessors方法负责调用Mybatis的后置处理器解析注册Mapper Bean,代码继承关系:

MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor implements BeanFactoryPostProcessor

3、finishBeanFactoryInitialization方法实现Mapper Bean实例化,并对ServiceBean注入;

 

——解析mapper接口,生成bean

Spring  invokeBeanFactoryPostProcessors方法委托PostProcessorRegistrationDelegate类进行后置处理器调用。

Spring: refresh()

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * 

Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

org.springframework.context.support.PostProcessorRegistrationDelegate

public static void invokeBeanFactoryPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set processedBeans = new HashSet();

    if (beanFactory instanceof BeanDefinitionRegistry) {
        // 这里要注意,后面要拿registry去注册,因为后面扫描类的参数是ClassPathMapperScanner,它的构造参数是BeanDefinitionRegistry
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List regularPostProcessors = new LinkedList();
        List registryProcessors = new LinkedList();
        // beanFactoryPostProcessors这时候还是空
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

        // Do not initialize FactoryBeans here: We need to leave all regular beans
        // uninitialized to let the bean factory post-processors apply to them!
        // Separate between BeanDefinitionRegistryPostProcessors that implement
        // PriorityOrdered, Ordered, and the rest.
        List currentRegistryProcessors = new ArrayList();

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 可以取到mybatis的后置处理器,但是不属于PriorityOrdered,所以这里还不会调用
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 可以取到mybatis的后置处理器,但是不属于Ordered,所以这里也不会调用
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        // 最后再来一次
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 看是否已经处理过了
                if (!processedBeans.contains(ppName)) {
                    // 还没处理
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // ★★★★★★ 最终调用后置处理 ★★★★★★
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    else {
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    List priorityOrderedPostProcessors = new ArrayList();
    List orderedPostProcessorNames = new ArrayList();
    List nonOrderedPostProcessorNames = new ArrayList();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        }
        else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List orderedPostProcessors = new ArrayList();
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // Finally, invoke all other BeanFactoryPostProcessors.
    List nonOrderedPostProcessors = new ArrayList();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

/**
 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection postProcessors, BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

 

对于Mybatis来讲,在初始化之前要首先完成注册,即:要完成BeanDefinition的生成以及在BeanDefinitionRegistry中的注册。

——进入Mybatis代码

org.mybatis.spring.mapper.MapperScannerConfigurer  implements  BeanDefinitionRegistryPostProcessor

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    if (this.processPropertyPlaceHolders) {
      processPropertyPlaceHolders();
    }
    // 这里ClassPathMapperScanner继承Spring:ClassPathBeanDefinitionScanner,由父类提供scan实现
    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
    scanner.setAddToConfig(this.addToConfig);
    scanner.setAnnotationClass(this.annotationClass);
    scanner.setMarkerInterface(this.markerInterface);
    scanner.setSqlSessionFactory(this.sqlSessionFactory);
    scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
    scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
    scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
    scanner.setResourceLoader(this.applicationContext);
    scanner.setBeanNameGenerator(this.nameGenerator);
    scanner.registerFilters();
    // 调用Spring父类扫描方法
    scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
}

 

这里回到spring代码,是要增强scan功能

org.springframework.context.annotation.ClassPathBeanDefinitionScanner

/**
 * Perform a scan within the specified base packages.
 * @param basePackages the packages to check for annotated classes
 * @return number of beans registered
 */
public int scan(String... basePackages) {
	int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

        // 子类有实现
	doScan(basePackages);

	// Register annotation config processors, if necessary.
	if (this.includeAnnotationConfig) {
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

	return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
/**
 * Perform a scan within the specified base packages,
 * returning the registered bean definitions.
 * 

This method does not register an annotation config processor * but rather leaves this up to the caller. * @param basePackages the packages to check for annotated classes * @return set of beans registered if any for tooling registration purposes (never {@code null}) */ // 这个方法会通过子类再调回来,因为解析的是目录下的接口,所有由Spring负责处理 protected Set doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); // 首先定义一个Set集合,对象是BeanDefinitionHolder,后面拿这个对象去注册 Set beanDefinitions = new LinkedHashSet(); for (String basePackage : basePackages) { // findCandidateComponents方法负责拿到mapper接口对应的BeanDefinition,这里是ScannedGenericBeanDefinition // 这个方法稍微复杂,要单独来一讲,不过里面的逻辑要清楚 // 就是根据路径解析得到BeanDefinition,包含Bean的各种描述信息 Set candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }

子类复写了父类的doScan方法,所以上面的doScan会走到子类,走子类主要的目的是processBeanDefinition方法,这个方法会给BeanDefinition设置必要的参数,比如:BeanClass=this.mapperFactoryBean.getClass(),告诉Spring这个是工厂Bean,到时候生成实例的时候通过工厂去实例化,工厂就是MapperFactoryBean。

org.mybatis.spring.mapper.ClassPathMapperScanner  extends ClassPathBeanDefinitionScanner

@Override
public Set doScan(String... basePackages) {
    // 这一步又反调了父类的doScan,说白了,就是子类想增强父类的doScna方法
	Set beanDefinitions = super.doScan(basePackages);
        // 走完上一步,mapper对应的Bean Definition以及解析出来了

	if (beanDefinitions.isEmpty()) {
		logger.warn("No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
	} else {
		processBeanDefinitions(beanDefinitions);
	}

	return beanDefinitions;
}


// 对bean definition进行处理
private void processBeanDefinitions(Set beanDefinitions) {
    GenericBeanDefinition definition;
    for (BeanDefinitionHolder holder : beanDefinitions) {
        definition = (GenericBeanDefinition) holder.getBeanDefinition();

        if (logger.isDebugEnabled()) {
            logger.debug("Creating MapperFactoryBean with name '" + holder.getBeanName() 
                + "' and '" + definition.getBeanClassName() + "' mapperInterface");
        }

        // the mapper interface is the original class of the bean
        // but, the actual class of the bean is MapperFactoryBean
        definition.getConstructorArgumentValues().addGenericArgumentValue(definition.getBeanClassName()); // issue #59
        // ★★★★★★ 设置BeanClass,mapperFactoryBean.getClass())
        definition.setBeanClass(this.mapperFactoryBean.getClass());

        definition.getPropertyValues().add("addToConfig", this.addToConfig);

        boolean explicitFactoryUsed = false;
        if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
            definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
            explicitFactoryUsed = true;
        } else if (this.sqlSessionFactory != null) {
            definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
            explicitFactoryUsed = true;
        }

        if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
            if (explicitFactoryUsed) {
                logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
            }
            definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
            explicitFactoryUsed = true;
        } else if (this.sqlSessionTemplate != null) {
            if (explicitFactoryUsed) {
                logger.warn("Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
            }
            definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
            explicitFactoryUsed = true;
        }

        if (!explicitFactoryUsed) {
            if (logger.isDebugEnabled()) {
                logger.debug("Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
            }
            definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        }
    }
}

——到此,Mybatis的XxxMapper BeanDefinition就已经注册好了,对应的就是Mapper接口。

 

——下面就是注入了

从上面分析可知Mybatis的Mapper Bean的BeanDefinition中,BeanClass是MapperFactoryBean,这就说明在注入的时候,一定是通过工厂Bean去创建具体的实例,所以在看代码前就要先了解:mybatis获取mapper bean(注入属性)是通过工厂Bean获取的,工厂Bean创建实例又是通过动态代理实现的,同时我们也知道,工厂Bean在Spring初始化过程中不会实例化,只有单例Bean会实例化。

简单来讲:mybatis的mapper bean是工厂bean,要给服务bean注入mapper bean,并不是直接拿这个mapper bean注入,【我要汽车,你不能给我一个工厂】,而应该用工厂bean动态代理出一个具体的bean给服务Bean,而这个动态代理对象就是最终的MapperProxy@xxxx。

业务代码:

@Component
public class UserService implements IUserService {

    @Autowired
    private UserMapper userMapper;
    
    @Override
    public String getUserName(Long userId) throws Exception {
        return userMapper.getUserName(userId);
    }

}

 

OK,进入获取代理bean的逻辑:

比较奇怪,凭什么你mybatis就是动态代理,工厂不能直接new吗?带着疑问进一步看代码。

不过这个调用链确实很长,我就不一一贴出来了,大致文字说明一下:

1 对服务Bean进行依赖注入 -> 2 注入对象是Mapper Bean -> 3 通过getBean方式获取 -> 4 getBean得到MapperBeanDefinition之后生成实例。

前面三步就不看了,直接看第四步:

org.springframework.beans.factory.support.AbstractBeanFactory

protected  T doGetBean(final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
    throws BeansException {
    // xxxxxxxxx 此处删除一万字

    // Create bean instance.
    // 如果你对这几行代码属性的话,说明基本能理解spring的初始化流程了
    // 为什么走这段,因为工厂是单例工厂
    if (mbd.isSingleton()) {
        // 这里getSingleton当然是get到了工厂bean
        sharedInstance = getSingleton(beanName, new ObjectFactory() {
            @Override
            public Object getObject() throws BeansException {
                try {
                    return createBean(beanName, mbd, args);
                }
                catch (BeansException ex) {
                    // Explicitly remove instance from singleton cache: It might have been put there
                    // eagerly by the creation process, to allow for circular reference resolution.
                    // Also remove any beans that received a temporary reference to the bean.
                    destroySingleton(beanName);
                    throw ex;
                }
            }
        });
        // 这一步就是通过工厂bean实例化具体的bean,重点在这里。。。。。
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }

    // xxxxxxxxx
}

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)) {
        // 如果不是工厂Bean报错
        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.
    // 这里注释很好懂,除非你就想要这个工厂Bean,但这里的name显然跟工厂名称不符
    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
        return beanInstance;
    }

    Object object = null;
    if (mbd == null) {
        // 先从缓存取,spring真是到处都是缓存。。。。。。。
        object = getCachedObjectForFactoryBean(beanName);
    }
    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;
} 
  

 

org.springframework.beans.factory.support.FactoryBeanRegistrySupport 

protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) {
    if (factory.isSingleton() && containsSingleton(beanName)) {
        synchronized (getSingletonMutex()) {
            Object object = this.factoryBeanObjectCache.get(beanName);
            if (object == null) { // 缓存不存在的
                object = doGetObjectFromFactoryBean(factory, beanName);
                // Only post-process and store if not put there already during getObject() call above
                // (e.g. because of circular reference processing triggered by custom getBean calls)
                Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                if (alreadyThere != null) {
                    object = alreadyThere;
                }
                else {
                    if (object != null && shouldPostProcess) {
                        if (isSingletonCurrentlyInCreation(beanName)) {
                            // Temporarily return non-post-processed object, not storing it yet..
                            return object;
                        }
                        beforeSingletonCreation(beanName);
                        try {
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        catch (Throwable ex) {
                            throw new BeanCreationException(beanName,
                                    "Post-processing of FactoryBean's singleton object failed", ex);
                        }
                        finally {
                            afterSingletonCreation(beanName);
                        }
                    }
                    if (containsSingleton(beanName)) {
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                    }
                }
            }
            return (object != NULL_OBJECT ? object : null);
        }
    }
    else {
        Object object = doGetObjectFromFactoryBean(factory, beanName);
        if (object != null && shouldPostProcess) {
            try {
                object = postProcessObjectFromFactoryBean(object, beanName);
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
            }
        }
        return object;
    }
}


private Object doGetObjectFromFactoryBean(final FactoryBean factory, final String beanName)
        throws BeanCreationException {

    Object object;
    try {
        if (System.getSecurityManager() != null) {
            AccessControlContext acc = getAccessControlContext();
            try {
                object = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                    @Override
                    public Object run() throws Exception {
                            return factory.getObject();
                        }
                    }, acc);
            }
            catch (PrivilegedActionException pae) {
                throw pae.getException();
            }
        }
        else {
            // 这里的factory就是MapperFactoryBean,注册mapper的时候专门篡改的。。。
            object = factory.getObject();
        }
    }
    catch (FactoryBeanNotInitializedException ex) {
        throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    }

    // Do not accept a null value for a FactoryBean that's not fully
    // initialized yet: Many FactoryBeans just return null then.
    if (object == null && isSingletonCurrentlyInCreation(beanName)) {
        throw new BeanCurrentlyInCreationException(
                beanName, "FactoryBean which is currently in creation returned null from getObject");
    }
    return object;
} 
  

 

org.mybatis.spring.mapper.MapperFactoryBean

@Override
public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
}

org.mybatis.spring.SqlSessionTemplate  ——这个类是专门给Spring整合用的

@Override
public  T getMapper(Class type) {
    return getConfiguration().getMapper(type, this);
}

org.apache.ibatis.session.Configuration 

public  T getMapper(Class type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);
}

org.apache.ibatis.binding.MapperRegistry

@SuppressWarnings("unchecked")
public  T getMapper(Class type, SqlSession sqlSession) {
	final MapperProxyFactory mapperProxyFactory = (MapperProxyFactory) knownMappers.get(type);
	if (mapperProxyFactory == null) {
		throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
	}
	try {
		return mapperProxyFactory.newInstance(sqlSession);
	} catch (Exception e) {
		throw new BindingException("Error getting mapper instance. Cause: " + e, e);
	}
}

org.apache.ibatis.binding.MapperProxyFactory

public T newInstance(SqlSession sqlSession) {
	final MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
	return newInstance(mapperProxy);
}

@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy mapperProxy) {
	return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

终于出来了,你以为结束了吗?  待续。。。

你可能感兴趣的:(Mybatis)