<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          @MapperScan 掃描包流程分析

          共 12628字,需瀏覽 26分鐘

           ·

          2021-06-08 23:46

          以下文章來(lái)源于武培軒,回復(fù)資源獲取資料

          前言

          其實(shí)一般不寫(xiě)這樣的分析的,但是這次呢一是為了記錄下來(lái)分析過(guò)程,二是給大家分享一下@MapperScan注解掃描包的流程吧。

          提出問(wèn)題

          @MapperScan("com.fast")掃描的是com.fast這個(gè)包下面的bean是毋庸置疑的,但是包括子包下面的bean嗎?

          疑問(wèn)案例

          比如com.fast.master.dao,還有com.fast.second.dao這些包下面的bean是否會(huì)一起被掃描到?

          分析

          1. 查看MapperScan注解,掃描包主要是這個(gè)@Import({MapperScannerRegistrar.class})
          @Retention(RetentionPolicy.RUNTIME)
          @Target({ElementType.TYPE})
          @Documented
          @Import({MapperScannerRegistrar.class})
          @Repeatable(MapperScans.class)
          public @interface MapperScan {
              String[] value() default {};

              String[] basePackages() default {};
               
              Class<?>[] basePackageClasses() default {};
               
              Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
               
              Class<? extends Annotation> annotationClass() default Annotation.class;
               
              Class<?> markerInterface() default Class.class;
               
              String sqlSessionTemplateRef() default "";
               
              String sqlSessionFactoryRef() default "";
               
              Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
          }
          1. 找到MapperScannerRegistrar.class看實(shí)現(xiàn)過(guò)程,就不全貼了,主要是這個(gè)注解這一塊
              void registerBeanDefinitions(AnnotationAttributes annoAttrs, BeanDefinitionRegistry registry) {
                  ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
                  Optional var10000 = Optional.ofNullable(this.resourceLoader);
                  Objects.requireNonNull(scanner);
                  var10000.ifPresent(scanner::setResourceLoader);
                  Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
                  if (!Annotation.class.equals(annotationClass)) {
                      scanner.setAnnotationClass(annotationClass);
                  }
                  Class<?> markerInterface = annoAttrs.getClass("markerInterface");
                  if (!Class.class.equals(markerInterface)) {
                      scanner.setMarkerInterface(markerInterface);
                  }
                  Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
                  if (!BeanNameGenerator.class.equals(generatorClass)) {
                      scanner.setBeanNameGenerator((BeanNameGenerator)BeanUtils.instantiateClass(generatorClass));
                  }
                  Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
                  if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
                      scanner.setMapperFactoryBeanClass(mapperFactoryBeanClass);
                  }
                  scanner.setSqlSessionTemplateBeanName(annoAttrs.getString("sqlSessionTemplateRef"));
                  scanner.setSqlSessionFactoryBeanName(annoAttrs.getString("sqlSessionFactoryRef"));
                  List<String> basePackages = new ArrayList();
                  basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));
                  basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));
                  basePackages.addAll((Collection)Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));
                  scanner.registerFilters();
                  scanner.doScan(StringUtils.toStringArray(basePackages));
              }

          這句周?chē)氖遣皇呛苁煜ぃ褪荕apperScan實(shí)現(xiàn)的注解,value,basePackages,basePackageClasses這幾個(gè)

          basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));
          basePackages.addAll((Collection)Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));
          basePackages.addAll((Collection)Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));
          scanner.registerFilters();
          scanner.doScan(StringUtils.toStringArray(basePackages));

          從scanner.doScan這句進(jìn)去,這里是開(kāi)始掃描包的地方

          1. 打開(kāi)調(diào)用的方法
          private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
                  Iterator var3 = beanDefinitions.iterator();

                  while(var3.hasNext()) {
                      BeanDefinitionHolder holder = (BeanDefinitionHolder)var3.next();
                      GenericBeanDefinition definition = (GenericBeanDefinition)holder.getBeanDefinition();
                      String beanClassName = definition.getBeanClassName();
                      LOGGER.debug(() -> {
                          return "Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + beanClassName + "' mapperInterface";
                      });
                      definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName);
                      definition.setBeanClass(this.mapperFactoryBeanClass);
                      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(() -> {
                                  return "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(() -> {
                                  return "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.";
                              });
                          }
                          definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
                          explicitFactoryUsed = true;
                      }
               
                      if (!explicitFactoryUsed) {
                          LOGGER.debug(() -> {
                              return "Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.";
                          });
                          definition.setAutowireMode(2);
                      }
                  }
              }
          1. 從這個(gè)方法第一行開(kāi)始debug,這里我使用@MapperScan("com.fast.framework.dao") 是掃描的com.fast.framework.dao包

          這個(gè)是掃描到的包,說(shuō)明會(huì)掃描到子包,perfect,解決了開(kāi)始提出的問(wèn)題。

          總結(jié)

          其實(shí)這里的分析過(guò)程不是特別詳細(xì),因?yàn)榈竭@里是證明掃描出來(lái)的包,從而間接證明掃描到的包都會(huì)被使用。剩下的:上一步怎么掃描的全部包,還有掃描到包怎么初始化的都沒(méi)有詳細(xì)分析。所以也是小水一篇吧,主要是要明白@MapperScan注解會(huì)掃描包的子包和學(xué)會(huì)這種分析思路。

          來(lái)源:blog.csdn.net/Mint6/article/details/92441513

          覺(jué)得不錯(cuò),請(qǐng)點(diǎn)個(gè)在看

          瀏覽 162
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品xxxxx | 一区=区三区四区 视频 | 插入 素芬 无码 | 草草影院视频在线观看视频 | 亚洲三级无码视频 |