ComponentScanParser解析@ComponentScan注解原理

本文详细描述了Spring框架中的ComponentScan注解解析器的工作原理,包括如何根据配置扫描指定类、使用默认过滤器、自定义扫描规则以及处理Bean的初始化和依赖关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

private final ComponentScanAnnotationParser componentScanParser ;
// 实际上 registry = ConfigurableListableBeanFactory 
// resourceLoader = new DefaultResourceLoader(); 
// componentScanBeanNameGenerator = new AnnotationBeanNameGenerator();
// environment = new StandardEnvironment();
this.componentScanParser = new ComponentScanAnnotationParser(Environment environment, ResourceLoader resourceLoader,BeanNameGenerator componentScanBeanNameGenerator,BeanDefinitionRegistry registry);
	// 解析配置declaringClass配置类信息,ComponentScan注解信息
	public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
		// 创建类路径下的BD的扫描器
		ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);{
			this.registry = registry;
			// 是否使用默认的扫描过滤器,默认为true
			if (useDefaultFilters) {
				// 添加默认的filter
				registerDefaultFilters();{
					// 扫描@Component
					this.includeFilters.add(new AnnotationTypeFilter(Component.class));
					// 扫描JSR的@ManagedBean注解
					this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
					// 扫描JSR中,@Named的类
					this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl))
				}
			}
			// 设置环境对象
			setEnvironment(environment);
			// 设置资源加载器
			setResourceLoader(resourceLoader);
		}
				
        // 获取componentScan注解中的属性
		Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
		// 设置BeanName的生成器
		boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
		scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass));
        // 设置Scoped的代理模式
		ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
		if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
			scanner.setScopedProxyMode(scopedProxyMode);
		}
		else {
		    // 设置作用域的解析器
			Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
			scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
		}
        // 设置资源扫描规则
		scanner.setResourcePattern(componentScan.getString("resourcePattern"));
        /// 获取需要添加的扫描过滤器
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter){
			                                List<TypeFilter> typeFilters = new ArrayList<>();
                                            FilterType filterType = filterAttributes.getEnum("type");
                                            // 根据过滤类型来添加对应的过滤器
                                            for (Class<?> filterClass : filterAttributes.getClassArray("classes")) {
                                                switch (filterType) {
                                                    case ANNOTATION:
                                                        Class<Annotation> annotationType = (Class<Annotation>) filterClass;
                                                        typeFilters.add(new AnnotationTypeFilter(annotationType));
                                                        break;
                                                    case ASSIGNABLE_TYPE:
                                                        typeFilters.add(new AssignableTypeFilter(filterClass));
                                                        break;
                                                    case CUSTOM:
                                                        TypeFilter filter = ParserStrategyUtils.instantiateClass(filterClass, TypeFilter.class,
                                                                this.environment, this.resourceLoader, this.registry);
                                                        typeFilters.add(filter);
                                                        break;
                                                    default:
                                                        throw new IllegalArgumentException("Filter type not supported with Class value: " + filterType);
                                                }
                                            }
                                            // 根据过滤规则来添加处理类
                                            for (String expression : filterAttributes.getStringArray("pattern")) {
                                                switch (filterType) {
                                                    case ASPECTJ:
                                                        typeFilters.add(new AspectJTypeFilter(expression, this.resourceLoader.getClassLoader()));
                                                        break;
                                                    case REGEX:
                                                        typeFilters.add(new RegexPatternTypeFilter(Pattern.compile(expression)));
                                                        break;
                                                    default:
                                                        throw new IllegalArgumentException("Filter type not supported with String pattern: " + filterType);
                                                }
                                            }
                                            return typeFilters;

			                            }) {
			}
				scanner.addIncludeFilter(typeFilter);
			}
		}
		// 获取需要排除的扫描过滤器
		for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
			for (TypeFilter typeFilter : typeFiltersFor(filter)) {
				scanner.addExcludeFilter(typeFilter);
			}
		}
        // 获取扫描的类是否是懒加载
		boolean lazyInit = componentScan.getBoolean("lazyInit");
		if (lazyInit) {
			scanner.getBeanDefinitionDefaults().setLazyInit(true);
		}
        // 获取需要扫描的包路径
		Set<String> basePackages = new LinkedHashSet<>();
		String[] basePackagesArray = componentScan.getStringArray("basePackages");
		for (String pkg : basePackagesArray) {
			String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
			Collections.addAll(basePackages, tokenized);
		}
		// 需要扫描的类,获取的是类对应的包名
		for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
			basePackages.add(ClassUtils.getPackageName(clazz));
		}
		// 如果没有配置basePackages,默认使用当前类的包名进行扫描
		if (basePackages.isEmpty()) {
			basePackages.add(ClassUtils.getPackageName(declaringClass));
		}
        // 添加排除过滤器,排除当前类传入的配置类
		scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
			@Override
			protected boolean matchClassName(String className) {
				return declaringClass.equals(className);
			}
		});
		// 开始扫描
		return scanner.doScan(StringUtils.toStringArray(basePackages));{
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            // 遍历所有需要扫描的包
            for (String basePackage : basePackages) {
                // 扫描所有的Bean
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);{
                    // 存在索引文件COMPONENTS_RESOURCE_LOCATION,META-INF/spring.components文件
                    if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
                        // 从spring.components加载给定Bean
                    	return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);{
                            Set<BeanDefinition> candidates = new LinkedHashSet<>();
                            Set<String> types = new HashSet<>();
                            for (TypeFilter filter : this.includeFilters) {
                                // 找到注解的类型
                                String stereotype = extractStereotype(filter);
                                if (stereotype == null) {
                                    throw new IllegalArgumentException("Failed to extract stereotype from " + filter);
                                }
                                // 保存注解对应的多个类
                                types.addAll(index.getCandidateTypes(basePackage, stereotype));
                            }
                            // 遍历找到的类
                            for (String type : types) {
                                MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(type);
                                // 判断当前类被TypeFilter过滤之后,是否满足扫描条件
                                if (isCandidateComponent(metadataReader)) {
                                    // 如果没有被过滤掉,是Bean,创建BD,保存起来
                                    AnnotatedGenericBeanDefinition sbd = new AnnotatedGenericBeanDefinition(metadataReader.getAnnotationMetadata());
                                    // 判断是否满足Bean的条件
                                    if (isCandidateComponent(sbd){
                                        AnnotationMetadata metadata = beanDefinition.getMetadata();
                                        // 1. 当前类是独立的,例如静态内部类和独立类,其他类不满足
                                        // 2. 当前类是否是具体的类,也就是非抽象类或者接口
                                        // 3. 当前类是抽象类,但是这个抽象类中有Lookup注解,也可以当成Bean
                                        return (metadata.isIndependent() && (metadata.isConcrete() ||
                                        				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
                                    }) {
                                    }
                                        candidates.add(sbd);
                                    }
                                }
                            }
                        return candidates;
                    }
                    else {
                        // 否则扫描所有的Bean
                        return scanCandidateComponents(basePackage);{
                            Set<BeanDefinition> candidates = new LinkedHashSet<>();
                            // 搜索的路径 classpath*:扫描的包路径/**/*.class
                            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern;
                            // 扫描路径上所有的类
                            Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
                            for (Resource resource : resources) {
                                if (resource.isReadable()) {
                                    MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
                                     // 判断当前类被TypeFilter过滤之后,是否满足扫描条件
                                    if (isCandidateComponent(metadataReader)) {
                                        ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                                        sbd.setResource(resource);
                                        sbd.setSource(resource);
                                        // 判断是否满足Bean的条件
                                        // 1. 当前类是独立的,例如静态内部类和独立类,其他类不满足
                                        // 2. 当前类是否是具体的类,也就是非抽象类或者接口
                                        // 3. 当前类是抽象类,但是这个抽象类中有Lookup注解,也可以当成Bean
                                        if (isCandidateComponent(sbd)) {
                                            candidates.add(sbd);
                                        }
                                    }
                                }
                            }
                            return candidates;
                        }
                    }
                }
                // 遍历找到的所有BD
                for (BeanDefinition candidate : candidates) {
                    // 设置Scope
                    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                    candidate.setScope(scopeMetadata.getScopeName());
                    // 设置BeanName
                    String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                    // 如果是BD类型(AbstractBeanDefinition),就执行默认值
                    if (candidate instanceof AbstractBeanDefinition) {
                        // 设置默认值
                        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);{
                            // new BeanDefinitionDefaults();
                            beanDefinition.applyDefaults(this.beanDefinitionDefaults);{
                                Boolean lazyInit = defaults.getLazyInit();
                                if (lazyInit != null) {
                                    setLazyInit(lazyInit);
                                }
                                setAutowireMode(defaults.getAutowireMode());
                                setDependencyCheck(defaults.getDependencyCheck());
                                setInitMethodName(defaults.getInitMethodName());
                                setEnforceInitMethod(false);
                                setDestroyMethodName(defaults.getDestroyMethodName());
                                setEnforceDestroyMethod(false);
                            }
                            if (this.autowireCandidatePatterns != null) {
                                beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
                            }
                        }
                    }
                    // 如果是注解的BD
                    if (candidate instanceof AnnotatedBeanDefinition) {
                        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);{
                            // 设置BD相关注解信息
                            AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
                            if (lazy != null) {
                                abd.setLazyInit(lazy.getBoolean("value"));
                            }
                            else if (abd.getMetadata() != metadata) {
                                lazy = attributesFor(abd.getMetadata(), Lazy.class);
                                if (lazy != null) {
                                    abd.setLazyInit(lazy.getBoolean("value"));
                                }
                            }

                            if (metadata.isAnnotated(Primary.class.getName())) {
                                abd.setPrimary(true);
                            }
                            AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
                            if (dependsOn != null) {
                                abd.setDependsOn(dependsOn.getStringArray("value"));
                            }

                            AnnotationAttributes role = attributesFor(metadata, Role.class);
                            if (role != null) {
                                abd.setRole(role.getNumber("value").intValue());
                            }
                            AnnotationAttributes description = attributesFor(metadata, Description.class);
                            if (description != null) {
                                abd.setDescription(description.getString("value"));
                            }
                        }
                    }
                    // 去重,判断当前BeanName是否被扫描过,因为包路径可以设置多个,可能存在包含关系,一个类可以被扫描多次
                    if (checkCandidate(beanName, candidate)) {
                        // 如果没有重复,将BD包装成BeanDefinitionHolder
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                        // 如果ScopedProxyMode为NO,表示当前BD不需要使用代理,否则需要使用代理
                        // 如果需要使用代理,则需要根据原来的BDH创建新的(代理)的BDH
                        // 这样到时候创建对象的时候,创建的可能是代理对象
                        definitionHolder =  AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                        beanDefinitions.add(definitionHolder);
                        // 将BD注册到BeanDefinitionRegistry中
                        registerBeanDefinition(definitionHolder, this.registry);
                    }
                }
            }
            return beanDefinitions;
		}
	}
				

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值