• 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:CodeAAAAAAAAAA20193262upgradetest	argetclassescomhcxycarmapperAccountMapper.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:CodeAAAAAAAAAA20193262upgradetest argetclassesmapperAccountMapper.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:CodeAAAAAAAAAA20193262upgradetest	argetclassesmapperAccountMapper.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:CodeAAAAAAAAAA20193262upgradetest	argetclassesmapperAccountMapper.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:CodeAAAAAAAAAA20193262upgradetest	argetclassesmapperAccountMapper.xml]
      }
    public void parse() { 
        if (!configuration.isResourceLoaded(resource)) {
          configurationElement(parser.evalNode("/mapper"));    //获取mapper标签,
          configuration.addLoadedResource(resource);   //resource  =  file [E:CodeAAAAAAAAAA20193262upgradetest	argetclassesmapperAccountMapper.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的动态代理。
      }
  • 相关阅读:
    Mysql游标的简明写法
    Sublime Text 介绍、用法、插件等
    [LeetCode#13] Roman to Integer
    [LeetCode#50] Pow(x, n)
    [LeetCode#240] Search a 2D Matrix II
    [LeetCode#238]Product of Array Except Self
    [LeetCode#171]Excel Sheet Column Number
    [LeetCode#258]Add Digits
    [LeetCode#264]Ugly Number II
    [LeetCode#263]Factorial Trailing Zeroes
  • 原文地址:https://www.cnblogs.com/yaowen/p/11956368.html
Copyright © 2020-2023  润新知