ComponentScans 解析

 1 // Process any @ComponentScan annotations
 2         Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
 3                 sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
 4         if (!componentScans.isEmpty() &&
 5                 !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
 6             for (AnnotationAttributes componentScan : componentScans) {
 7                 // The config class is annotated with @ComponentScan -> perform the scan immediately
 8                 //开始对@ComponentScan进行解析处理,会扫描出所有的bean的信息
 9                 Set<BeanDefinitionHolder> scannedBeanDefinitions =
10                         this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
11                 // Check the set of scanned definitions for any further config classes and parse recursively if needed
12                 for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
13                     BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
14                     if (bdCand == null) {
15                         bdCand = holder.getBeanDefinition();
16                     }
17                     if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
18                         parse(bdCand.getBeanClassName(), holder.getBeanName());
19                     }
20                 }
21             }
22         }

 

 1 public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
 2         ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
 3                 componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
 4     //判断是否重写了bean的命名规则,一般不会
 5         Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
 6         boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
 7         scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
 8                 BeanUtils.instantiateClass(generatorClass));
 9       
10         ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
11         if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
12             scanner.setScopedProxyMode(scopedProxyMode);
13         }
14         else {
15             Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
16             scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
17         }
18 
19         scanner.setResourcePattern(componentScan.getString("resourcePattern"));
20      //需要扫描的注解
21         for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
22             for (TypeFilter typeFilter : typeFiltersFor(filter)) {
23                 scanner.addIncludeFilter(typeFilter);
24             }
25         }
      //排除扫描的注解
26 for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { 27 for (TypeFilter typeFilter : typeFiltersFor(filter)) { 28 scanner.addExcludeFilter(typeFilter); 29 } 30 } 31 32 boolean lazyInit = componentScan.getBoolean("lazyInit"); 33 if (lazyInit) { 34 scanner.getBeanDefinitionDefaults().setLazyInit(true); 35 } 36 37 Set<String> basePackages = new LinkedHashSet<>(); 38 String[] basePackagesArray = componentScan.getStringArray("basePackages"); 39 for (String pkg : basePackagesArray) { 40 String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg), 41 ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); 42 Collections.addAll(basePackages, tokenized); 43 } 44 for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) { 45 basePackages.add(ClassUtils.getPackageName(clazz)); 46 }
       //默认会获取主类的路径,根据主类的路径范围来扫描
47 if (basePackages.isEmpty()) { 48 basePackages.add(ClassUtils.getPackageName(declaringClass)); 49 } 50 51 scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { 52 @Override 53 protected boolean matchClassName(String className) { 54 return declaringClass.equals(className); 55 } 56 });
       //上面的准备工作完成后开始真正解析
57 return scanner.doScan(StringUtils.toStringArray(basePackages)); 58 }

 

 1 protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
 2         Assert.notEmpty(basePackages, "At least one base package must be specified");
 3         Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
 4         for (String basePackage : basePackages) {
 5         //findCandidateComponents()是public方法可以被调用,作用是扫描出basePackage范围内的bean
 6         //如果我们自己想判断代码中是否有特定的注解,就可以调用scan的这个方法
 7         //比如:判读代码中是否有EnableScheduling注解,如果有则candidateComponents.size()>0
 8         /*
 9          ClassPathScanningCandidateComponentProvider scanner = getScanner();//自定义
10         scanner.setResourceLoader(this.resourceLoader);
11         AnnotationTypeFilter enableSchedulingFilter = new AnnotationTypeFilter(EnableScheduling.class);
12         scanner.addIncludeFilter(enableSchedulingFilter);
13         String basePackage = ClassUtils.getPackageName(metadata.getClassName());
14         Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents(basePackage);
15         */
16             Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
17             for (BeanDefinition candidate : candidates) {
18             //获取候选bean的作用域
19                 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
20                 candidate.setScope(scopeMetadata.getScopeName());
21                 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
22                 //通过findCandidateComponents可知candidate是ScannedGenericBeanDefinition的实例
23                 //而ScannedGenericBeanDefinition是AbstractBeanDefinition、AnnotatedBeanDefinition的实现类,所以一般二个if都会进入
24                 if (candidate instanceof AbstractBeanDefinition) {
25                     postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
26                 }
27                 if (candidate instanceof AnnotatedBeanDefinition) {
28                     AnnotationConfigUtils.    ((AnnotatedBeanDefinition) candidate);
29                 }
30                 if (checkCandidate(beanName, candidate)) {
31                     BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
32                     definitionHolder =
33                             AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
34                     beanDefinitions.add(definitionHolder);
35                     registerBeanDefinition(definitionHolder, this.registry);
36                 }
37             }
38         }
39         return beanDefinitions;
40     }

 

posted @ 2021-05-10 17:40  龙之谷2019  阅读(385)  评论(0)    收藏  举报