前面我们讲解了自定义命名空间过程及其如何去创建自定义命名空间解析器、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));}
进入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);}
因为我们当前节点标签为
public BeanDefinition parse(Element element, ParserContext parserContext) {//获取需要扫描的包路径base-packageString 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);//扫描带特定配置注解的类,如@componentSet beanDefinitions = scanner.doScan(basePackages);//组件注册(包括注册一些内部的注解后置处理器、触发注册事件)registerComponents(parserContext.getReaderContext(), beanDefinitions, element);return null;}
configureScanner(parserContext, element),见方法1详解
scanner.doScan(basePackages),见方法6详解
registerComponents(parserContext.getReaderContext(), beanDefinitions, element),见方法18详解
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {//默认配置过滤器,如@Component及其带@Component注解的@Service、@Controllerboolean 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;}
createScanner(parserContext.getReaderContext(),见方法2详解
parseTypeFilters(element, scanner, parserContext),见方法4详解
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,readerContext.getEnvironment(), readerContext.getResourceLoader());}
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);}
registerDefaultFilters(),见方法3详解
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.}}
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());}}}}
createTypeFilter((Element) node, classLoader, parserContext),见方法5详解
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) 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);}}
xml配置文件示例如下:
protected Set doScan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");Set beanDefinitions = new LinkedHashSet<>();//遍历对包进行扫描for (String basePackage : basePackages) {//通过解析扫描,经过过滤后的BeanDefinitionSet candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {//解析设置Scope元属性信息ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());//生成bean名称,如果没有名称注解,则使用默认生成,以首字母小写类名为beanNameString beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {//给当前BeanDefinition设置默认值postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {//解析设置一些公共属性值,包括@Lazy, @Primary, @DependsOn, @Role, @DescriptionAnnotationConfigUtils.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;}
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详解
public Set findCandidateComponents(String basePackage) {//默认componentsIndex 为空,会走下面逻辑if (this.componentsIndex != null && indexSupportsIncludeFilters()) {return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);}else {return scanCandidateComponents(basePackage);}}
进入 scanCandidateComponents(basePackage)
private Set scanCandidateComponents(String basePackage) {Set candidates = new LinkedHashSet<>();try {//拼接查询的包路径,如classpath*:service/scan/**/*.classString 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;}
isCandidateComponent(metadataReader),见方法8详解
isCandidateComponent(sbd),见方法9详解
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;}
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()))));}
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;}
这里会创建ScopeMetadata类,默认Scope属性值为Singleton,解析是否有@Scope注解值,有则解析设置。
@Overridepublic 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*/@Nullableprotected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {//获取元注解信息AnnotationMetadata amd = annotatedDef.getMetadata();//获取注解类型Set 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;}
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));}}
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);}
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"));}//解析设置@RoleAnnotationAttributes role = attributesFor(metadata, Role.class);if (role != null) {abd.setRole(role.getNumber("value").intValue());}//解析设置@DescriptionAnnotationAttributes description = attributesFor(metadata, Description.class);if (description != null) {abd.setDescription(description.getString("value"));}}
protected boolean checkCandidate(String beanName, BeanDefinition beanDefinition) throws IllegalStateException {//判断已经注册缓存中是否存在该beanNameif (!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() + "]");}
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);}
ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass),见方法16详解
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,BeanDefinitionRegistry registry, boolean proxyTargetClass) {//获取原始beanNameString originalBeanName = definition.getBeanName();//获取原始BeanDefinition BeanDefinition targetDefinition = definition.getBeanDefinition();//为原始beanName重新生成一个名称,原始BeanName名称加上前缀 scopedTarget.String targetBeanName = getTargetBeanName(originalBeanName);//使用ScopedProxyFactoryBean作为要创建代理的BeanDefinitionRootBeanDefinition 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());//添加类属性,值为新生成的beanNameproxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);if (proxyTargetClass) {//使用Cglib代理方式,设置属性值,ScopedProxyFactoryBean的该属性默认就为truetargetDefinition.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());}
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);}
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);}}}
注册过程,我们在解析默认命名空间配置的时候也有讲解到,主要往三个缓存添加beanDefinitionMap、beanDefinitionNames、aliasMap。
protected void registerComponents(XmlReaderContext readerContext, Set 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 processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}readerContext.fireComponentRegistered(compositeDef);}
AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source),见方法19详解
public static Set 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 beanDefs = new LinkedHashSet(4);// 3.注册内部管理的用于处理@Configuration注解的后置处理器的beanif (!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注解的后置处理器的beanif (!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注解的后置处理器的beanif (!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注解的后置处理器的beanif (!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;}
registerPostProcessor方法,见方法20详解
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);}
到这里 < 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实例化初始化工作。
上一篇:Pyecharts绘制动态地图