spring mybatis1

getBeanPostProcessors()就是所有的后置处理器,就是拦截器,就是责任链模式。

spring和mybatis的桥梁在于
MybatisAutoConfiguration,MapperFactoryBean

## 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/upgrade?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

  ## Mybatis 配置
mybatis.typeAliasesPackage=com.hcxy.car.bean
mybatis.mapperLocations=classpath:mapper/*.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>springboot</groupId>
    <artifactId>springboot-mybatis</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-mybatis</name>

    <!-- Spring Boot 启动父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.12.RELEASE</version>
    </parent>

    <properties>
        <mybatis-spring-boot>1.2.0</mybatis-spring-boot>
        <mysql-connector>5.1.39</mysql-connector>
    </properties>

    <dependencies>

        <!-- Spring Boot Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring Boot Test 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- Spring Boot Mybatis 依赖 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis-spring-boot}</version>
        </dependency>

        <!-- MySQL 连接驱动依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector}</version>
        </dependency>

    </dependencies>
</project>
SpringApplication.run(App.class, args);

public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
        return new SpringApplication(sources).run(args);
    }

public SpringApplication(Object... sources) {
        initialize(sources);
    }
private void initialize(Object[] sources) {
        if (sources != null && sources.length > 0) {
            this.sources.addAll(Arrays.asList(sources));
        }
        this.webEnvironment = deduceWebEnvironment();
        setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
        setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = deduceMainApplicationClass();
    }

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type) {
        return getSpringFactoriesInstances(type, new Class<?>[] {});
    }
private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,Class<?>[] parameterTypes, Object... args) {
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        Set<String> names = new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
        List<T> instances = createSpringFactoriesInstances(type, parameterTypes,classLoader, args, names);
        AnnotationAwareOrderComparator.sort(instances);
        return instances;
    }
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
        String factoryClassName = factoryClass.getName();
        try {
            Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            List<String> result = new ArrayList<String>();
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));
                String factoryClassNames = properties.getProperty(factoryClassName);
                result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
            }
            return result;
        }
    }
解析accountController的时候:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   {//accountController,

        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);  //accountController依赖注入accountMapper
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);
            }
        }

        return exposedObject;
    }
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { //accountController依赖注入accountMapper
        if (hasInstAwareBpps || needsDepCheck) { 
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) { 
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        applyPropertyValues(beanName, mbd, bw, pvs);
    }
CommonAnnotationBeanPostProcessor类:
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)  {

        InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);//com.hcxy.car.mapper.AccountMapper
        try {
            metadata.inject(bean, beanName, pvs);
        }
        return pvs;
    }
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable { 
        if (!elementsToIterate.isEmpty()) { 
            for (InjectedElement element : elementsToIterate) { 
                element.inject(target, beanName, pvs);   //mapper.AccountMapper,依赖注入进了AccountController,
            }
        }
    }
protected void inject(Object target, String requestingBeanName, PropertyValues pvs) throws Throwable {
            if (this.isField) {
                Field field = (Field) this.member;  //private com.hcxy.car.mapper.AccountMapper com.hcxy.car.controller.AccountController.accountMapper
                ReflectionUtils.makeAccessible(field);
                field.set(target, getResourceToInject(target, requestingBeanName));   //accountMapper设置到了accountController去了。
            } 
        }
CommonAnnotationBeanPostProcessor类:
protected Object getResourceToInject(Object target, String requestingBeanName) {
            return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
                    getResource(this, requestingBeanName));   //this = ResourceElement for private com.hcxy.car.mapper.AccountMapper com.hcxy.car.controller.AccountController.accountMapper,requestingBeanName = accountController
        }
protected Object getResource(LookupElement element, String requestingBeanName) throws BeansException { 
        return autowireResource(this.resourceFactory, element, requestingBeanName);
    }
protected Object autowireResource(BeanFactory factory, LookupElement element, String requestingBeanName)  { 
 
        else {
            resource = factory.getBean(name, element.lookupType);   //name = accountMapper,lookupType = interface com.hcxy.car.mapper.AccountMapper。  //返回accountMapper的代理:org.apache.ibatis.binding.MapperProxy()
            autowiredBeanNames = Collections.singleton(name);
        }

        if (factory instanceof ConfigurableBeanFactory) {
            ConfigurableBeanFactory beanFactory = (ConfigurableBeanFactory) factory;
            for (String autowiredBeanName : autowiredBeanNames) {
                if (beanFactory.containsBean(autowiredBeanName)) {
                    beanFactory.registerDependentBean(autowiredBeanName, requestingBeanName);   //accountMapper加到spring的容器,
                }
            }
        }

        return resource;  //返回MapperProxy
    }
//创建accountMapper
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)   {//accountMapper,

        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);  //beanName = accountMapper,instanceWrapper = org.springframework.beans.BeanWrapperImpl: wrapping object [org.mybatis.spring.mapper.MapperFactoryBean@40bf4386]
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);  //返回MapperFactoryBean,没做什么,
            }
        }

        return exposedObject;
    }
1。populateBean  accountMapper
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {  

if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);   //beanName = accountMapper,mbd = Root bean: class [org.mybatis.spring.mapper.MapperFactoryBean];  [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\com\hcxy\car\mapper\AccountMapper.class]
            }

        if (hasInstAwareBpps || needsDepCheck) {
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);    //
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            } 
        }

        applyPropertyValues(beanName, mbd, bw, pvs); //beanName  =  accountMapper,pvs = [bean property 'addToConfig', bean property 'sqlSessionFactory', bean property 'sqlSessionTemplate']
    }
1。1,accountMapper解析依赖注入sqlSessionFactory,sqlSessionTemplate
protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

        TypeConverter converter = getCustomTypeConverter();   //org.springframework.beans.BeanWrapperImpl: wrapping object [org.mybatis.spring.mapper.MapperFactoryBean@40bf4386] 

        Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);//sqlSessionFactory,sqlSessionTemplate
        for (String propertyName : propertyNames) {//sqlSessionFactory,sqlSessionTemplate
            try {
                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName); //org.springframework.beans.GenericTypeAwarePropertyDescriptor[name=sqlSessionFactory],org.springframework.beans.GenericTypeAwarePropertyDescriptor[name=sqlSessionTemplate]
                if (Object.class != pd.getPropertyType()) {
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);    //method 'setSqlSessionFactory' 
                    boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);  //method 'setSqlSessionFactory' ,method 'setSqlSessionTemplate' parameter 0,
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);  //返回DefaultSqlSessionFactory, SqlSessionTemplate,
if (autowiredArgument != null) {
                        pvs.add(propertyName, autowiredArgument);   //pvs = [bean property 'addToConfig', bean property 'sqlSessionFactory', bean property 'sqlSessionTemplate']
                    }
                }
            } 
        }
    }
accountMapper解析依赖注入sqlSessionFactory,sqlSessionTemplate
public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { else { if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); //DefaultSqlSessionFactory, } return result; } }
public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
            Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { 
        try { 
            Class<?> type = descriptor.getDependencyType();  //interface org.apache.ibatis.session.SqlSessionFactory
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);   //null 
 
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);  //{@9038} sqlSessionFactory -> {@7048} "interface org.apache.ibatis.session.SqlSessionFactory"  
            else { 
                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
                autowiredBeanName = entry.getKey();//sqlSessionFactory
                instanceCandidate = entry.getValue();//interface org.apache.ibatis.session.SqlSessionFactory
            }

            if (autowiredBeanNames != null) {
                autowiredBeanNames.add(autowiredBeanName);  //sqlSessionFactory
            }
            return (instanceCandidate instanceof Class ?
                    descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);   //sqlSessionFactory,interface org.apache.ibatis.session.SqlSessionFactory,
        }
        finally {
            ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
        }
    }
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)  {
        return beanFactory.getBean(beanName, requiredType);  //sqlSessionFactory,interface org.apache.ibatis.session.SqlSessionFactory,
    }
获取SqlSessionFactory的实例。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  {   //sqlSessionFactory,factoryBeanName=org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration; factoryMethodName=sqlSessionFactory;[org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);   //org.springframework.beans.BeanWrapperImpl: wrapping object [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@21e5f0b6]。 //返回DefaultSqlSessionFactory。
        } 
 
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);   //sqlSessionFactory,没做什么
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);    //没做什么
            }
        }  
        return exposedObject;
    }
1。1。1 ,createBeanInstance sqlSessionFactory
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { 
        if (mbd.getFactoryMethodName() != null)  {   //sqlSessionFactory
            return instantiateUsingFactoryMethod(beanName, mbd, args);    // factoryBeanName=org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration; factoryMethodName=sqlSessionFactory;  [org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class]。 //返回DefaultSqlSessionFactory。
        }
    }
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
        return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);   //beanName = sqlSessionFactory,返回DefaultSqlSessionFactory。
    }
public BeanWrapper instantiateUsingFactoryMethod( final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) {  //beanName = sqlSessionFactory,
        String factoryBeanName = mbd.getFactoryBeanName();   //MybatisAutoConfiguration
        if (factoryBeanName != null) { 
           factoryBean = this.beanFactory.getBean(factoryBeanName);    //开始获取MybatisAutoConfiguration,创建sqlSessionFactory时候获取MybatisAutoConfiguration,返回class MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$bb43e1a8。创建MybatisAutoConfiguration的时候createBeanInstance方法中直接走return autowireConstructor(beanName, mbd, ctors, args);方法返回,会去getBean(“MybatisProperties”)等,
            factoryClass = factoryBean.getClass();//class MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$bb43e1a8
            isStatic = false;
        }   

        if (factoryMethodToUse == null || argsToUse == null) { 
            factoryClass = ClassUtils.getUserClass(factoryClass);   //class org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 
            Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]);   //public  SqlSessionFactory  MybatisAutoConfiguration.sqlSessionFactory(javax.sql.DataSource)     
 
            for (Method candidate : candidates) { //public  SqlSessionFactory  MybatisAutoConfiguration.sqlSessionFactory(javax.sql.DataSource)      

                if (paramTypes.length >= minNrOfArgs) { 

                    if (resolvedValues != null) { 
                        try { 
                            argsHolder = createArgumentArray(
                                    beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);   //里面会去getBean("dataSource"),getBean("dataSource")里面会去getBean(“jdbc.DataSourceConfiguration$Tomcat”),又会去getBean("jdbc.DataSourceProperties"),又会去getBean("dataSourceInitializer"),又会去getBean("jdbc.DataSourceAutoConfiguration"),
                        } 
                    }  
                }
            } 
        }

        try {  
            else {
                beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
                        mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);    //调用MybatisAutoConfiguration的sqlSessionFactory方法,返回DefaultSqlSessionFactory。
            } 
            bw.setBeanInstance(beanInstance);
            return bw;     //返回DefaultSqlSessionFactory。
        } 
    }
factoryBean = this.beanFactory.getBean(factoryBeanName);     //创建sqlSessionFactory时候创建MybatisAutoConfiguration,
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {    //MybatisAutoConfiguration
        instanceWrapper = createBeanInstance(beanName, mbd, args);//依赖注入MybatisProperties
        try {
            populateBean(beanName, mbd, instanceWrapper);    //没有做什么
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd); //没有做什么
            }
        } 
        }
        return exposedObject;
    }
MybatisAutoConfiguration的sqlSessionFactory方法,

public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception { SqlSessionFactoryBean factory = new SqlSessionFactoryBean(); factory.setDataSource(dataSource); if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) { factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage()); //com.hcxy.car.bean } if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) { factory.setMapperLocations(this.properties.resolveMapperLocations()); //file [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\mapper\AccountMapper.xml] } return factory.getObject(); //DefaultSqlSessionFactory, }
SqlSessionFactoryBean的getObject():此时就进到mybatis的解析。
public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }
    return this.sqlSessionFactory;
  } 
public void afterPropertiesSet() throws Exception {  
    this.sqlSessionFactory = buildSqlSessionFactory();    //DefautSqlSessionFactory
  }
protected SqlSessionFactory buildSqlSessionFactory() throws IOException { 

    if (hasLength(this.typeAliasesPackage)) {
      String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
          ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);   //com.hcxy.car.bean 
    }     
    if (this.transactionFactory == null) {
      this.transactionFactory = new SpringManagedTransactionFactory();
    } 
    if (!isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {   //file [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\mapper\AccountMapper.xml]
          continue;
        }
        try {
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
              configuration, mapperLocation.toString(), configuration.getSqlFragments());
          xmlMapperBuilder.parse();
        }   
      }
    }  
    return this.sqlSessionFactoryBuilder.build(configuration);     //configuration里面解析了接口AccountMapper和AccountMapper.xml文件,[namespace:com.hcxy.car.mapper.AccountMapper, interface com.hcxy.car.mapper.AccountMapper, file [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\mapper\AccountMapper.xml]]
  }
public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map<String, XNode> sqlFragments) {
    this(new XPathParser(inputStream, true, configuration.getVariables(), new XMLMapperEntityResolver()),
        configuration, resource, sqlFragments);
  }

public XPathParser(InputStream inputStream, boolean validation, Properties variables, EntityResolver entityResolver) {
    commonConstructor(validation, variables, entityResolver);
    this.document = createDocument(new InputSource(inputStream));    //file [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\mapper\AccountMapper.xml]
  }
public void parse() { 
    if (!configuration.isResourceLoaded(resource)) {
      configurationElement(parser.evalNode("/mapper"));    //获取mapper标签,
      configuration.addLoadedResource(resource);   //resource  =  file [E:\Code\AAAAA\AAAAA\2019326\2\upgradetest\target\classes\mapper\AccountMapper.xml]
      bindMapperForNamespace();
    }
  }
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.hcxy.car.mapper.AccountMapper">
    <resultMap id="BaseResultMap" type="account">
        <id column="id" property="id" jdbcType="INTEGER" />
        <result column="name" property="name" jdbcType="INTEGER" />
    </resultMap>
    <select id="findAll" resultMap="BaseResultMap">
        select ac.id ,ac.name
        from aa ac
    </select>
</mapper>
private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");   //com.hcxy.car.mapper.AccountMapper
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
      resultMapElements(context.evalNodes("/mapper/resultMap"));     //解析resultMap标签,
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));    //解析select标签,
  }
private void bindMapperForNamespace() {
    String namespace = builderAssistant.getCurrentNamespace();   //com.hcxy.car.mapper.AccountMapper
    if (namespace != null) {
      Class<?> boundType = null;
      try {
        boundType = Resources.classForName(namespace);    //interface com.hcxy.car.mapper.AccountMapper
      }  
      if (boundType != null) {
        if (!configuration.hasMapper(boundType)) { 
          configuration.addLoadedResource("namespace:" + namespace);
          configuration.addMapper(boundType);
        }
      }
    }
  }
public SqlSessionFactory build(Configuration config) {
  return new DefaultSqlSessionFactory(config);
  }
accountMapper解析依赖注入 ,sqlSessionTemplate

public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { else { if (result == null) { result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter); //method 'setSqlSessionTemplate' parameter 0, } return result;//返回SqlSessionTemplate。 } }
return (instanceCandidate instanceof Class ? descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)  {
        return beanFactory.getBean(beanName, requiredType);   //获取sqlSessionTemplate实例,
    }
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)  {   //sqlSessionTemplate,
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);    //返回SqlSessionTemplate。
        } 
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);   //没做什么
            if (exposedObject != null) {
                exposedObject = initializeBean(beanName, exposedObject, mbd);//没做什么
            }
        } 
        return exposedObject;
    }
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { 
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);   //sqlSessionTemplate
        }  
    }
public BeanWrapper instantiateUsingFactoryMethod( final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { 
        String factoryBeanName = mbd.getFactoryBeanName();    //MybatisAutoConfiguration,
        if (factoryBeanName != null) { 
            factoryBean = this.beanFactory.getBean(factoryBeanName);    //获取MybatisAutoConfiguration实例,在SqlSessionFactory时候,已经实例化了,这里不用实例化了。
            factoryClass = factoryBean.getClass();    //class org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration$$EnhancerBySpringCGLIB$$615bec6a
            isStatic = false;
        }   

        if (factoryMethodToUse == null || argsToUse == null) { 
            factoryClass = ClassUtils.getUserClass(factoryClass);  //class org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration 
            AutowireUtils.sortFactoryMethods(candidates);  //public SqlSessionTemplate MybatisAutoConfiguration.sqlSessionTemplate(org.apache.ibatis.session.SqlSessionFactory)  
  
            for (Method candidate : candidates) {//public SqlSessionTemplate MybatisAutoConfiguration.sqlSessionTemplate(org.apache.ibatis.session.SqlSessionFactory)   
                if (paramTypes.length >= minNrOfArgs) { 
                    if (resolvedValues != null) { 
                        try { 
                            argsHolder = createArgumentArray( beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);//sqlSessionTemplate,factoryBeanName=MybatisAutoConfiguration; factoryMethodName=sqlSessionTemplate;[org/mybatis/spring/boot/autoconfigure/MybatisAutoConfiguration.class],
                        } 
                    }  
                }
            }  
        }
        try {  
            else {
                beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse);   //调用MybatisAutoConfiguration的sqlSessionTemplate方法,返回SqlSessionTemplate。
            } 
            bw.setBeanInstance(beanInstance);
            return bw;
        } 
    }
调用MybatisAutoConfiguration的sqlSessionTemplate方法,
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { //sqlSessionFactory = DefaultSqlSessionFactory return executorType != null ? new SqlSessionTemplate(sqlSessionFactory, executorType) : new SqlSessionTemplate(sqlSessionFactory); } public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType()); }
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {   //beanName  =  accountMapper,pvs  =   [bean property 'addToConfig', bean property 'sqlSessionFactory', bean property 'sqlSessionTemplate']  
 
        else {
            original = Arrays.asList(pvs.getPropertyValues());    //[bean property 'addToConfig', bean property 'sqlSessionFactory', bean property 'sqlSessionTemplate']  
        }
 
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));    //deepCopy   =   [bean property 'addToConfig', bean property 'sqlSessionFactory', bean property 'sqlSessionTemplate']  ,bw是accountMapper = org.springframework.beans.BeanWrapperImpl: wrapping object [org.mybatis.spring.mapper.MapperFactoryBean@61ab89b0]
        } 
    }
方法的调用:
@RequestMapping(value = "/all", method = RequestMethod.GET)
    public Map<String, Object> all1(HttpServletRequest request, HttpServletResponse response) {
        List<Account> l = null; 
        l = accountMapper.findAll(); 
    };

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }

result = sqlSession.<E>selectList(command.getName(), param);    //sqlSession  =  SqlSessionTemplate
SqlSessionTemplate类:
public <E> List<E> selectList(String statement, Object parameter) {
    return this.sqlSessionProxy.<E> selectList(statement, parameter);  //sqlSessionProxy  =  DefaultSqlSession
  }
private class SqlSessionInterceptor implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      SqlSession sqlSession = getSqlSession(
          SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType,
          SqlSessionTemplate.this.exceptionTranslator);
      try {
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) { 
          sqlSession.commit(true);
        }
        return result;
      }  finally {
        if (sqlSession != null) {
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }
      }
    }
  }
DefaultSqlSessionFactory类:
public SqlSession openSession(ExecutorType execType) {
    return openSessionFromDataSource(execType, null, false);
  }

DefaultSqlSession类:
public <E> List<E> selectList(String statement, Object parameter) {
    return this.selectList(statement, parameter, RowBounds.DEFAULT);
  }

public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    }  
  }
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

 

populateBean(beanName, mbd, instanceWrapper);    //beanName = userMapper
依赖注入userMapper时候还会依赖注入:mybatis-org.mybatis.spring.boot.autoconfigure.MybatisProperties,org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration,org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration$Hikari,spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties,dataSource,org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerInvoker,sqlSessionFactory,sqlSessionTemplate,

exposedObject = initializeBean(beanName, exposedObject, mbd);     //beanName = userMapper,exposedObject = MapperFactoryBean里面有mapperInterface=interface com.example.mapper.UserMapper,sqlSession=SqlSessionTemplate。SqlSessionTemplate里面有sqlSessionFactory=DefaultSqlSessionFactory。

getBean(userMapper)之后,就要Mapper的生成代理,过程:

if (mbd.isSingleton()) {
   sharedInstance = getSingleton(beanName, () -> { return createBean(beanName, mbd, args); });    //获取mapper实例,sharedInstance =MapperFactoryBean,里面有mapperInterface=interface com.example.mapper.UserMapper,sqlSession=SqlSessionTemplate。SqlSessionTemplate里面有sqlSessionFactory=DefaultSqlSessionFactory。
   bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {    
        if (object == null) { 
            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;    //factory = MapperFactoryBean
            if (mbd == null && containsBeanDefinition(beanName)) {
                mbd = getMergedLocalBeanDefinition(beanName);
            }
            boolean synthetic = (mbd != null && mbd.isSynthetic());
            object = getObjectFromFactoryBean(factory, beanName, !synthetic);//factory = MapperFactoryBean,beanName = userMapper。
        }
        return object;
    }
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); //factory = MapperFactoryBean,beanName = userMapper。 
                }
                return object;     //返回org.apache.ibatis.binding.MapperProxy(就是动态代理)。
            }
        } 
    }
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)  { 
        try { 
            else {
                object = factory.getObject();//factory = MapperFactoryBean ,返回org.apache.ibatis.binding.MapperProxy(就是动态代理)。
            }
        }  
        return object;
    }
MapperFactoryBean类:
public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);   //getSqlSession()返回SqlSessionTemplate,
  }
SqlSessionTemplate类:
public <T> T getMapper(Class<T> type) {
    return getConfiguration().getMapper(type, this);
  }
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    return mapperRegistry.getMapper(type, sqlSession);   //type = interface com.example.mapper.UserMapper,sqlSession = SQLSessionTemplate
  }
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);   //MapperProxyFactory
    try {
      return mapperProxyFactory.newInstance(sqlSession);
    }  
  }
MapperProxyFactory类:
  public T newInstance(SqlSession sqlSession) {
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);//SQLSessionTemplate,interface com.example.mapper.UserMapper,
    return newInstance(mapperProxy);
  }
protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);   //jdk的动态代理。
  }

 

posted @ 2019-11-29 10:54  无天666  阅读(370)  评论(0编辑  收藏  举报