• Spring IOC源码:<context:component-scan>源码详解


    Spring源码系列:

    Spring IOC源码:简单易懂的Spring IOC 思路介绍
    Spring IOC源码:核心流程介绍
    Spring IOC源码:ApplicationContext刷新前准备工作
    Spring IOC源码:obtainFreshBeanFactory 详解(上)
    Spring IOC源码:obtainFreshBeanFactory 详解(中)
    Spring IOC源码:obtainFreshBeanFactory 详解(下)
    Spring IOC源码:<context:component-scan>源码详解
    Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解
    Spring IOC源码:registerBeanPostProcessors 详解
    Spring IOC源码:实例化前的准备工作
    Spring IOC源码:finishBeanFactoryInitialization详解
    Spring IoC源码:getBean 详解
    Spring IoC源码:createBean( 上)
    Spring IoC源码:createBean( 中)
    Spring IoC源码:createBean( 下)
    Spring IoC源码:finishRefresh 完成刷新详解

    前言

    前面我们讲解了自定义命名空间过程及其如何去创建自定义命名空间解析器、xsd文件等,实现了一个demo。这节学习一下< context:component-scan>标签对包进行扫描。

    正文

    回到自定义标签解析方法中:

    	public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
    		//获取命名空间处理器地址
    		String namespaceUri = getNamespaceURI(ele);
    		if (namespaceUri == null) {
    			return null;
    		}
    		//加载处理器
    		NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
    		if (handler == null) {
    			error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
    			return null;
    		}
    		//查找解析器进行处理
    		return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    进入handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

    	public BeanDefinition parse(Element element, ParserContext parserContext) {
    		//根据节点标签查找解析器
    		BeanDefinitionParser parser = findParserForElement(element, parserContext);
    		return (parser != null ? parser.parse(element, parserContext) : null);
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    因为我们当前节点标签为,所以查找后的解析器为ComponentScanBeanDefinitionParser。

    	public BeanDefinition parse(Element element, ParserContext parserContext) {
    		//获取需要扫描的包路径base-package
    		String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    		//解析占位符
    		basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    		//根据这些“,; \t\n”符号进行切割;如:com.zdc.project1;com.zdc.project2 	
    		String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
    				ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
    
    		// 创建配置扫描器
    		ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    		//扫描带特定配置注解的类,如@component
    		Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    		//组件注册(包括注册一些内部的注解后置处理器、触发注册事件)
    		registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
    
    		return null;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    configureScanner(parserContext, element),见方法1详解
    scanner.doScan(basePackages),见方法6详解
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element),见方法18详解

    方法1:configureScanner

    	protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
    		//默认配置过滤器,如@Component及其带@Component注解的@Service、@Controller
    		boolean useDefaultFilters = true;
    		if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
    			//如果有配置该属性,则解析获取
    			useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
    		}
    
    		// 创建扫描器
    		ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
    		//设置Bean默认解析配置
    		scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
    		//设置自动注入候选模式
    		scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
    		//设置resource-pattern属性
    		if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
    			scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
    		}
    
    		try {
    		//解析设置name-generator属性
    			parseBeanNameGenerator(element, scanner);
    		}
    		catch (Exception ex) {
    			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    		}
    
    		try {
    			//解析设置scope-resolver、scoped-proxy属性,scope-resolver、scoped-proxy不能同时存在,反正抛异常
    			parseScope(element, scanner);
    		}
    		catch (Exception ex) {
    			parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    		}
    		//解析设置过滤器
    		parseTypeFilters(element, scanner, parserContext);
    
    		return scanner;
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    createScanner(parserContext.getReaderContext(),见方法2详解
    parseTypeFilters(element, scanner, parserContext),见方法4详解

    方法2:createScanner

    	protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
    		return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
    				readerContext.getEnvironment(), readerContext.getResourceLoader());
    	}
    
    • 1
    • 2
    • 3
    • 4
    	public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
    			Environment environment, @Nullable ResourceLoader resourceLoader) {
    
    		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    		this.registry = registry;
    		//如果使用默认过滤器
    		if (useDefaultFilters) {
    			registerDefaultFilters();
    		}
    		setEnvironment(environment);
    		setResourceLoader(resourceLoader);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    registerDefaultFilters(),见方法3详解

    方法3:registerDefaultFilters

    	protected void registerDefaultFilters() {
    		//添加@Component注解类型
    		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
    		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
    		try {
    			//添加ManagedBean注解类型
    			this.includeFilters.add(new AnnotationTypeFilter(
    					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
    			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
    		}
    		catch (ClassNotFoundException ex) {
    			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
    		}
    		try {
    			//添加Named注解类型
    			this.includeFilters.add(new AnnotationTypeFilter(
    					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
    			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
    		}
    		catch (ClassNotFoundException ex) {
    			// JSR-330 API not available - simply skip.
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    方法4:parseTypeFilters

    protected void parseTypeFilters(Element element, ClassPathBeanDefinitionScanner scanner, ParserContext parserContext) {
    		// Parse exclude and include filter elements.
    		ClassLoader classLoader = scanner.getResourceLoader().getClassLoader();
    		//获取子节点标签列表
    		NodeList nodeList = element.getChildNodes();
    		for (int i = 0; i < nodeList.getLength(); i++) {
    			Node node = nodeList.item(i);
    			if (node.getNodeType() == Node.ELEMENT_NODE) {
    				//获取节点标签名称
    				String localName = parserContext.getDelegate().getLocalName(node);
    				try {
    					//如果为
    					if (INCLUDE_FILTER_ELEMENT.equals(localName)) {
    						//解析节点属性信息
    						TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
    						scanner.addIncludeFilter(typeFilter);
    					}
    					//如果为
    					else if (EXCLUDE_FILTER_ELEMENT.equals(localName)) {
    					  //解析节点属性信息
    						TypeFilter typeFilter = createTypeFilter((Element) node, classLoader, parserContext);
    						scanner.addExcludeFilter(typeFilter);
    					}
    				}
    				catch (ClassNotFoundException ex) {
    					parserContext.getReaderContext().warning(
    							"Ignoring non-present type filter class: " + ex, parserContext.extractSource(element));
    				}
    				catch (Exception ex) {
    					parserContext.getReaderContext().error(
    							ex.getMessage(), parserContext.extractSource(element), ex.getCause());
    				}
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    createTypeFilter((Element) node, classLoader, parserContext),见方法5详解

    方法5:createTypeFilter

    protected TypeFilter createTypeFilter(Element element, @Nullable ClassLoader classLoader,
    			ParserContext parserContext) throws ClassNotFoundException {
    		//获取type属性值
    		String filterType = element.getAttribute(FILTER_TYPE_ATTRIBUTE);
    		//获取expression属性值
    		String expression = element.getAttribute(FILTER_EXPRESSION_ATTRIBUTE);
    		//解析占位符
    		expression = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(expression);
    		//下面根据不同的类型创建不同的过滤器类
    		if ("annotation".equals(filterType)) {
    			return new AnnotationTypeFilter((Class<Annotation>) ClassUtils.forName(expression, classLoader));
    		}
    		else if ("assignable".equals(filterType)) {
    			return new AssignableTypeFilter(ClassUtils.forName(expression, classLoader));
    		}
    		else if ("aspectj".equals(filterType)) {
    			return new AspectJTypeFilter(expression, classLoader);
    		}
    		else if ("regex".equals(filterType)) {
    			return new RegexPatternTypeFilter(Pattern.compile(expression));
    		}
    		else if ("custom".equals(filterType)) {
    			Class<?> filterClass = ClassUtils.forName(expression, classLoader);
    			if (!TypeFilter.class.isAssignableFrom(filterClass)) {
    				throw new IllegalArgumentException(
    						"Class is not assignable to [" + TypeFilter.class.getName() + "]: " + expression);
    			}
    			return (TypeFilter) BeanUtils.instantiateClass(filterClass);
    		}
    		else {
    			throw new IllegalArgumentException("Unsupported filter type: " + filterType);
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    xml配置文件示例如下:

    	<context:component-scan base-package="service.scan"
    							annotation-config="true"
    							name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"
    							resource-pattern="**/*.class"
    							scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver"
    							use-default-filters="false">
    		
    		<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
    		
    		<context:include-filter type="assignable" expression="service.scan.domain.Teacher"/>
    
    		
    		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    		<context:exclude-filter type="assignable" expression="service.scan.domain.College"/>
    		
    		<context:exclude-filter type="regex" expression=".service.*"/>
    
    
    	context:component-scan>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    方法6:doScan

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    		Assert.notEmpty(basePackages, "At least one base package must be specified");
    		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
    		//遍历对包进行扫描
    		for (String basePackage : basePackages) {
    			//通过解析扫描,经过过滤后的BeanDefinition
    			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
    			for (BeanDefinition candidate : candidates) {
    				//解析设置Scope元属性信息
    				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
    				candidate.setScope(scopeMetadata.getScopeName());
    				//生成bean名称,如果没有名称注解,则使用默认生成,以首字母小写类名为beanName
    				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
    				if (candidate instanceof AbstractBeanDefinition) {
    					//给当前BeanDefinition设置默认值
    					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
    				}
    				if (candidate instanceof AnnotatedBeanDefinition) {
    					//解析设置一些公共属性值,包括@Lazy, @Primary, @DependsOn, @Role, @Description
    					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;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    findCandidateComponents(basePackage),见方法7
    this.scopeMetadataResolver.resolveScopeMetadata(candidate),见方法10详解
    this.beanNameGenerator.generateBeanName(candidate, this.registry),见方法11详解
    postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName),见方法12详解
    AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate),见方法13详解
    checkCandidate(beanName, candidate),见方法14详解
    AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);,见方法15详解
    registerBeanDefinition(definitionHolder, this.registry),将方法17详解

    方法7:findCandidateComponents

    	public Set<BeanDefinition> findCandidateComponents(String basePackage) {
    		//默认componentsIndex 为空,会走下面逻辑
    		if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
    			return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
    		}
    		else {
    			return scanCandidateComponents(basePackage);
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    进入 scanCandidateComponents(basePackage)

    private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
    		Set<BeanDefinition> candidates = new LinkedHashSet<>();
    		try {
    			//拼接查询的包路径,如classpath*:service/scan/**/*.class
    			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
    					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
    			//解析包下的所有文件资源路径,
    			//如file [D:\Code\SourceCode\LeanCode\Spring\spring-framework-5.2.0.RELEASE\learn-test\build\classes\java\main\service\scan\dao\StudentDao.class]
    			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
    			boolean traceEnabled = logger.isTraceEnabled();
    			boolean debugEnabled = logger.isDebugEnabled();
    			for (Resource resource : resources) {
    				if (traceEnabled) {
    					logger.trace("Scanning " + resource);
    				}
    				if (resource.isReadable()) {
    					try {
    						//获取元注解属性
    						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
    						//根据过滤器判断进行校验
    						if (isCandidateComponent(metadataReader)) {
    							//创建ScannedGenericBeanDefinition类用于封装扫描出来类的属性
    							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
    							sbd.setResource(resource);
    							sbd.setSource(resource);
    							// 判断sbd是否为候选类(独立的 && (具体的实现类 || (抽象类 && 类中有方法使用@Lookup注解)))
    							if (isCandidateComponent(sbd)) {
    								if (debugEnabled) {
    									logger.debug("Identified candidate component class: " + resource);
    								}
    								candidates.add(sbd);
    							}
    							else {
    								if (debugEnabled) {
    									logger.debug("Ignored because not a concrete top-level class: " + resource);
    								}
    							}
    						}
    						else {
    							if (traceEnabled) {
    								logger.trace("Ignored because not matching any filter: " + resource);
    							}
    						}
    					}
    					catch (Throwable ex) {
    						throw new BeanDefinitionStoreException(
    								"Failed to read candidate component class: " + resource, ex);
    					}
    				}
    				else {
    					if (traceEnabled) {
    						logger.trace("Ignored because not readable: " + resource);
    					}
    				}
    			}
    		}
    		catch (IOException ex) {
    			throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
    		}
    		return candidates;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    isCandidateComponent(metadataReader),见方法8详解
    isCandidateComponent(sbd),见方法9详解

    方法8:isCandidateComponent

    	protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
    		//根据不同的过滤器类型进行不同逻辑的解析处理,用于排除
    		for (TypeFilter tf : this.excludeFilters) {
    			if (tf.match(metadataReader, getMetadataReaderFactory())) {
    				return false;
    			}
    		}
    		//根据不同的过滤器类型进行不同逻辑的解析处理,用于添加
    		for (TypeFilter tf : this.includeFilters) {
    			// 如果metadataReader与includeFilters中的任意一个TypeFilter匹配(如果tf为Component注解:metadataReader对应的类使用了Component则匹配),
        
    			if (tf.match(metadataReader, getMetadataReaderFactory())) {
    				// 判断是由有@Conditional;如果有,则返回true,表示metadataReader对应的类为候选类
    				return isConditionMatch(metadataReader);
    			}
    		}
    		return false;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    方法9:isCandidateComponent

    	protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
    		AnnotationMetadata metadata = beanDefinition.getMetadata();
    		// isIndependent:确定底层类是否是独立的,即它是否是顶级类或嵌套类(静态内部类),它可以独立于封闭类构造。
    		// isConcrete:返回底层类是表示具体类,即:既不是接口也不是抽象类。
    		// isAbstract:返回底层类是否标记为抽象。
    		// hasAnnotatedMethods:确定基础类是否具有使用给定注解(@Lookup)类型进行注解(或元注解)的任何方法。
    
    		return (metadata.isIndependent() && (metadata.isConcrete() ||
    				(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    方法10:resolveScopeMetadata

    	public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    		//创建ScopeMetadata,默认属性为singleton 单例
    		ScopeMetadata metadata = new ScopeMetadata();
    		if (definition instanceof AnnotatedBeanDefinition) {
    			AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
    			//获取Scope属性
    			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
    					annDef.getMetadata(), this.scopeAnnotationType);
    			if (attributes != null) {
    				//不为空,设置Scope属性
    				metadata.setScopeName(attributes.getString("value"));
    				// 解析proxyMode属性
    				ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
    				if (proxyMode == ScopedProxyMode.DEFAULT) {
    					proxyMode = this.defaultProxyMode;
    				}
    				metadata.setScopedProxyMode(proxyMode);
    			}
    		}
    		return metadata;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这里会创建ScopeMetadata类,默认Scope属性值为Singleton,解析是否有@Scope注解值,有则解析设置。

    方法11:generateBeanName

    	@Override
    	public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    		if (definition instanceof AnnotatedBeanDefinition) {
    			String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
    			if (StringUtils.hasText(beanName)) {
    				// Explicit bean name found.
    				return beanName;
    			}
    		}
    		// 构建默认名称,以类名并且第一个字母小写
    		return buildDefaultBeanName(definition, registry);
    	}
    
    	/**
    	 * Derive a bean name from one of the annotations on the class.
    	 * @param annotatedDef the annotation-aware bean definition
    	 * @return the bean name, or {@code null} if none is found
    	 */
    	@Nullable
    	protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
    		//获取元注解信息
    		AnnotationMetadata amd = annotatedDef.getMetadata();
    		//获取注解类型
    		Set<String> types = amd.getAnnotationTypes();
    		String beanName = null;
    		for (String type : types) {
    			//获取value属性
    			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
    			//判断是否ManagedBean、Component、Named注解,及其attributes 是否有value属性
    			if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
    				Object value = attributes.get("value");
    				if (value instanceof String) {
    					String strVal = (String) value;
    					if (StringUtils.hasLength(strVal)) {
    						if (beanName != null && !strVal.equals(beanName)) {
    							throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
    									"component names: '" + beanName + "' versus '" + strVal + "'");
    						}
    						beanName = strVal;
    					}
    				}
    			}
    		}
    		return beanName;
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    方法12:postProcessBeanDefinition

    	protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
    		//给当前BeanDefinition设置默认一些配置值,
    		beanDefinition.applyDefaults(this.beanDefinitionDefaults);
    		if (this.autowireCandidatePatterns != null) {
    			//设置AutowireCandidate属性默认为true,代表可以被其它类注入
    			beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    	public void applyDefaults(BeanDefinitionDefaults defaults) {
    		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);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方法13:processCommonDefinitionAnnotations

    public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
    		processCommonDefinitionAnnotations(abd, abd.getMetadata());
    	}
    
    	static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
    		//获取@Lazy注解,并设置属性值
    		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"));
    			}
    		}
    		//获取设置@Primary,当属性注入有多个时,配置了Primary将作为首先
    		if (metadata.isAnnotated(Primary.class.getName())) {
    			abd.setPrimary(true);
    		}
    		//解析设置@DependsOn,设置该类依赖其它类,被依赖类也会被创建管理
    		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
    		if (dependsOn != null) {
    			abd.setDependsOn(dependsOn.getStringArray("value"));
    		}
    		//解析设置@Role
    		AnnotationAttributes role = attributesFor(metadata, Role.class);
    		if (role != null) {
    			abd.setRole(role.getNumber("value").intValue());
    		}
    		//解析设置@Description
    		AnnotationAttributes description = attributesFor(metadata, Description.class);
    		if (description != null) {
    			abd.setDescription(description.getString("value"));
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    方法14:checkCandidate

    	protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {
    		//判断已经注册缓存中是否存在该beanName
    		if (!this.registry.containsBeanDefinition(beanName)) {
    			return true;
    		}
    		//获取已存在的BeanDefinition 
    		BeanDefinition existingDef = this.registry.getBeanDefinition(beanName);
    		//获取原始BeanDefinition ,代理的会有原始值
    		BeanDefinition originatingDef = existingDef.getOriginatingBeanDefinition();
    		if (originatingDef != null) {
    			existingDef = originatingDef;
    		}
    		//检查新BeanDefinition是否与原BeanDefinition兼容,如果兼容则返回false,跳过注册
    		if (isCompatible(beanDefinition, existingDef)) {
    			return false;
    		}
    		throw new ConflictingBeanDefinitionException("Annotation-specified bean name '" + beanName +
    				"' for bean class [" + beanDefinition.getBeanClassName() + "] conflicts with existing, " +
    				"non-compatible bean definition of same name and class [" + existingDef.getBeanClassName() + "]");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    方法15:applyScopedProxyMode

    	static BeanDefinitionHolder applyScopedProxyMode(
    			ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
    		
    		ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
    		//如果不代理,则返回原始值
    		if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
    			return definition;
    		}
    		//判断代理方式,基于类还是基于接口;基于类:使用Cglib,基于接口:JDK动态代理
    		boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
    		return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass),见方法16详解

    方法16:createScopedProxy

    	public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
    			BeanDefinitionRegistry registry, boolean proxyTargetClass) {
    		//获取原始beanName
    		String originalBeanName = definition.getBeanName();
    		//获取原始BeanDefinition 
    		BeanDefinition targetDefinition = definition.getBeanDefinition();
    		//为原始beanName重新生成一个名称,原始BeanName名称加上前缀 scopedTarget.
    		String targetBeanName = getTargetBeanName(originalBeanName);
    
    		
    		//使用ScopedProxyFactoryBean作为要创建代理的BeanDefinition
    		RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
    		// 将原始bean封装成BeanDefinitionHolder,设置到代理的decoratedDefinition属性
    		proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
    		//设置代理的原始BeanDefinition属性值
    		proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
    		proxyDefinition.setSource(definition.getSource());
    		proxyDefinition.setRole(targetDefinition.getRole());
    		//添加类属性,值为新生成的beanName
    		proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
    		if (proxyTargetClass) {
    			//使用Cglib代理方式,设置属性值,ScopedProxyFactoryBean的该属性默认就为true
    			targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
    			// ScopedProxyFactoryBean's "proxyTargetClass" default is TRUE, so we don't need to set it explicitly here.
    		}
    		else {
    			//使用JDK动态代理方式,设置属性值
    			proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
    		}
    
    		// Copy autowire settings from original bean definition.
    		//拷贝原始对象的信息
    		proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
    		proxyDefinition.setPrimary(targetDefinition.isPrimary());
    		if (targetDefinition instanceof AbstractBeanDefinition) {
    			proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
    		}
    
    		// The target bean should be ignored in favor of the scoped proxy.
    		//原始的Bean不被其它类所注入
    		targetDefinition.setAutowireCandidate(false);
    		targetDefinition.setPrimary(false);
    
    		// Register the target bean as separate bean in the factory.
    		//原始bean注册到缓存中
    		registry.registerBeanDefinition(targetBeanName, targetDefinition);
    
    		// Return the scoped proxy definition as primary bean definition
    		// (potentially an inner bean).
    		//将代理bean封装成BeanDefinitionHolder对象并返回
    		return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    方法17:registerBeanDefinition

    	protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
    		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
    	}
    
    • 1
    • 2
    • 3
    	public static void registerBeanDefinition(
    			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    			throws BeanDefinitionStoreException {
    
    		// Register bean definition under primary name.
    		String beanName = definitionHolder.getBeanName();
    		//往beanDefinitionNames放BeanName,往beanDefinitionMap放 
    		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
    
    		// Register aliases for bean name, if any.
    		String[] aliases = definitionHolder.getAliases();
    		if (aliases != null) {
    			//往aliasMap放 
    			for (String alias : aliases) {
    				registry.registerAlias(beanName, alias);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    注册过程,我们在解析默认命名空间配置的时候也有讲解到,主要往三个缓存添加beanDefinitionMap、beanDefinitionNames、aliasMap。

    方法18:registerComponents

    	protected void registerComponents(
    			XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
    
    		Object source = readerContext.extractSource(element);
    		//获取标签节点名称,并封装成CompositeComponentDefinition 对象
    		CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
    		//将扫描到的所有BeanDefinition添加到compositeDef的nestedComponents属性中
    		for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
    			compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
    		}
    
    		// Register annotation config processors, if necessary.
    		boolean annotationConfig = true;
    		//获取annotation-config属性值
    		if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
    			annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
    		}
    		if (annotationConfig) {
    			//注册并返回一些默认配置的后置处理器
    			Set<BeanDefinitionHolder> processorDefinitions =
    					AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
    			for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
    				compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
    			}
    		}
    
    		readerContext.fireComponentRegistered(compositeDef);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source),见方法19详解

    方法19:registerAnnotationConfigProcessors

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    			BeanDefinitionRegistry registry, @Nullable Object source) {
    
    		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    	    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                // 1.设置dependencyComparator属性
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                // 2.设置autowireCandidateResolver属性(设置自动注入候选对象的解析器,用于判断BeanDefinition是否为候选对象)
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }
     
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
     
        // 3.注册内部管理的用于处理@Configuration注解的后置处理器的bean
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 3.1 registerPostProcessor: 注册BeanDefinition到注册表中
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
     
        // 4.注册内部管理的用于处理@Autowired、@Value、@Inject以及@Lookup注解的后置处理器的bean
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
     
        // 5.注册内部管理的用于处理@Required注解的后置处理器的bean
        if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
     
        // 6.注册内部管理的用于处理JSR-250注解(例如@Resource, @PostConstruct, @PreDestroy)的后置处理器的bean
        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
     
        // 7.注册内部管理的用于处理JPA注解的后置处理器的bean
        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition();
            try {
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            } catch (ClassNotFoundException ex) {
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }
     
        // 8.注册内部管理的用于处理@EventListener注解的后置处理器的bean
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }
        // 9.注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }
     
        return beanDefs;
    
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    registerPostProcessor方法,见方法20详解

    方法20:registerPostProcessor

    	private static BeanDefinitionHolder registerPostProcessor(
    			BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
    		//设置默认Role属性
    		definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    		//往beanDefinitionMap、beanDefinitionNames缓存放入
    		registry.registerBeanDefinition(beanName, definition);
    		//新建包装类
    		return new BeanDefinitionHolder(definition, beanName);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    到这里 < context:component-scan> 节点解析已经完成了

    总结

    整个解析过程已经做了一遍了,现在梳理一下流程:
    1、获取包路径、对路径进行占位符替换,根据“,;\n\t”解析成路径数组
    2、创建扫描器,解析配置过滤器,如果是默认过滤器则include加入默认注解属性,如:Compenent、ManagedBean、Named;以及自定义过滤器属性处理,如:


    3、开始扫描,遍历包路径,拼接通配符,加载包下面的资源,如xxx.class
    4、 扫描出类,加载元注解属性,并经过过滤器处理。
    5、得到BeanDinifition后,设置公共属性,判断是否需要代理,以及解析代理方法是使用Cglib,还是JDK动态代理
    6、注册到上下文缓存中,beanDefinitionMap、beanDefinitionNames、aliasMap。
    7、添加了几个内部的注解相关的后置处理器:ConfigurationClassPostProcessor、AutowiredAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor 等。

    本章就讲解到这里,整个解析工作告一段落了。后面开始讲解IOC 流程中的后置处理器处理,及其多播器等,最后再进入最核心部分,Bean实例化初始化工作。

  • 相关阅读:
    Leetcode 101. 对称二叉树
    HDU_7149
    非常全的一份Python爬虫的Xpath博文
    mysql 注入
    2024年csdn最新最全pytest系列——pytest-rerunfailures插件之测试用例失败重跑
    猿创征文|网络安全的十大经典工具介绍
    小程序OCR身份证识别
    文件操作及IO
    HTML+CSS+JavaScript仿京东购物网站制作 html静态网页设计制作 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计
    自己学习Cesium的笔记简介
  • 原文地址:https://blog.csdn.net/weixin_45031612/article/details/127855882