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 }