验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

基于Spring怎么整合mybatis的mapper

阅读:1115 来源:乙速云 作者:代码code

基于Spring怎么整合mybatis的mapper

      Spring整合mybatis的mapper生成过程

      基于Spring怎么整合mybatis的mapper

      mapperScannerConfigurer实现了BeandifinitionRegistryPostProcessor

      后置处理beanFactory时会调用其postProcessBeanDefinitionRegistry

      基于Spring怎么整合mybatis的mapper

      public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
          if (this.processPropertyPlaceHolders) {
            processPropertyPlaceHolders();
          }
       
          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.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);
          scanner.registerFilters();
      //扫描包集合,注册mapper的beandifinition
          scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
        }

      基于Spring怎么整合mybatis的mapper

      ClassPathMapperScanner#doScan

      public Set doScan(String... basePackages) {
          Set beanDefinitions = super.doScan(basePackages);
       
          if (beanDefinitions.isEmpty()) {
            LOGGER.warn(() -> "No MyBatis mapper was found in '" + Arrays.toString(basePackages) + "' package. Please check your configuration.");
          } else {
      //会对bean信息进行一些更改和添加,如设置propertyValues,向其中添加sqlsessionFactory等属性信息等
            processBeanDefinitions(beanDefinitions);
          }
       
          return beanDefinitions;
        }

      ClassPathBeanDefinitionScanner#doScan

      protected Set doScan(String... basePackages) {
      		Assert.notEmpty(basePackages, "At least one base package must be specified");
      		Set beanDefinitions = new LinkedHashSet<>();
      		for (String basePackage : basePackages) {
      //遍历集合扫描包,获取包下的可用的mapper信息
      			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;
      	}

       基于Spring怎么整合mybatis的mapper

      如上在进行包扫描时,会调用ClassPathBeanDefinitionScanner#doScan,进行beanDefinition的扫描和注册

      执行完后调用ClassPathMapperScanner#processBeanDefinitions

      private void processBeanDefinitions(Set beanDefinitions) {
      //有省略部分
             
          //这里有遍历所有mapper
      //将所有mapper的beanClass改为了mapperFactoryBean,最后生成的bean也是该类型的,只有在用到的
      //时候才会调用getObject生成mapper
            definition.setBeanClass(this.mapperFactoryBeanClass);
      //接下来是添加一些MapperFactoryBean的属性信息到beandefinition里,在生成实例的时候,会根据
      //此处传入的值来进行具体设置,如sqlsessionFactory
            definition.getPropertyValues().add("addToConfig", this.addToConfig);
       
            
            if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
              definition.getPropertyValues().add("sqlSessionFactory", new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
            
            } else if (this.sqlSessionFactory != null) {
              definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
              
            }
       
            if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
              
              definition.getPropertyValues().add("sqlSessionTemplate", new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
              
            } else if (this.sqlSessionTemplate != null) {
              
              definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
              
            }
        }

      确定了所有的mapper的beanDefinition为MapperFactoryBean类型后,

      确定在生成的bean皆为MapperFactoryBean,在getBean时会调用MapperFactoryBean#getObject

      基于Spring怎么整合mybatis的mapper

      mapperInterface是在MapperFactoryBean创建时,会调用有参构造创建实例,值是创建是

      基于Spring怎么整合mybatis的mapper

      基于Spring怎么整合mybatis的mapper

       构造方法参数的获取从mdb中

      基于Spring怎么整合mybatis的mapper

      创建除了传入mapperInterface,还会在设置属性值时调用MapperFactoryBean的父类SqlSessionDaoSupport#setSqFactory 将mdb中的sqlsessionfactory传入其中

      基于Spring怎么整合mybatis的mapper

      mdb的sqlsessionFactory信息来历

      基于Spring怎么整合mybatis的mapper

      查看方法栈调用,可以看到在开始填充属性时会去mdb中判断是否有propertyValue,如果有就返回,这就是之前扫描mapper后ClassPathMapperScanner#processBeanDefinitions对mdb的一些设置

      在创造service时,如果有@Autowire 注入mapper,在createBean时会调用getObject

      mdb只有一份,可得sqlsessionfactory即只有一份,sqlsessionTemplate一个mapper一份。

    分享到:
    *特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
    相关文章
    {{ v.title }}
    {{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
    你可能感兴趣
    推荐阅读 更多>