Spring源码解析(二)-自定义标签的解析
2022/2/21 1:26:25
本文主要是介绍Spring源码解析(二)-自定义标签的解析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
上一小节完成了对默认标签的属性及其子标签的解析和注册,接下来会对自定义标签的解析和注册过程进行详细的讲解,这个过程与前面讲解的子标签中的自定义属性和自定义子标签有些相似,不过功能却大有不同,也是十分重要,解析完自定义标签后,就基本上完成了所有需要实例化的bean封装成BeanDefinition的任务。
BeanDefinitionParserDelegate - 1021 - N44 public BeanDefinition parseCustomElement(Element ele) { //N45 下面就开始解析自定义标签,其实跟解析默认标签中的自定义属性和标签思路是一样的 return this.parseCustomElement(ele, (BeanDefinition)null); }
BeanDefinitionParserDelegate - 1026 - N45 public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) { //根据node获取到命名空间uri例如前面N18上的图中 //context的uri是:http://www.springframework.org/schema/context String namespaceUri = this.getNamespaceURI(ele); if (namespaceUri == null) { return null; } else { //N30 这个resolve方法跟解析默认标签中的自定义属性和标签那里是一样的(N27中),返回一个处理器 //这个处理器的init方法在resolve中被调用,初始化了所有解析对象到map中(parsers这个map) NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } else { //N46 这一步就是调用相对应的处理器的处理方法parse() return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); } } }
NamespaceHandlerSupport - 26 - N46 public BeanDefinition parse(Element element, ParserContext parserContext) { //N47 这个跟N32中的findDecoratorForNode()方法很类似,只是这里不是获取装饰器而是获取解析对象 BeanDefinitionParser parser = this.findParserForElement(element, parserContext); //N48 调用解析对象的parse()方法,这里我拿我们每个人都用过的 //<context:component-scan base-package="com.kaka"></context:component-scan> //这个自定义标签的解析对象ComponentScanBeanDefinitionParser来讲解下它的大致流程,其他解析类的流程是相通的。 return parser != null ? parser.parse(element, parserContext) : null; }
NamespaceHandlerSupport - 32 - N47 //这个方法和N33很类似,N33是获取装饰器这里是获取解析对象,他们是存储在NamespaceHandlerSupport中的三个map中 private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) { //<context:component-scan>标签中localName就是:后面的component-scan String localName = parserContext.getDelegate().getLocalName(element); //通过localName拿到对应的解析对象,这里拿到的是ComponentScanBeanDefinitionParser这个类的实例 BeanDefinitionParser parser = (BeanDefinitionParser)this.parsers.get(localName); if (parser == null) { parserContext.getReaderContext().fatal("Cannot locate BeanDefinitionParser for element [" + localName + "]", element); } return parser; }
ComponentScanBeanDefinitionParser - 50 - N48 public BeanDefinition parse(Element element, ParserContext parserContext) { //获取到标签中base-package属性的值 String basePackage = element.getAttribute("base-package"); basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage); //将basePackage字符串以,切割开来得到basePackages数组,这个数组包含的包就是我们接下来要扫描的包,那扫描包里的什么呢?? String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ",; \t\n"); //N49 创建扫描器,在创建扫描器的时候就会创建过滤器来规定过滤哪些注解,忽略哪些注解 ClassPathBeanDefinitionScanner scanner = this.configureScanner(parserContext, element); //N53 扫描并把扫描的类封装成beanDefinition对象 核心方法 Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages); //N64 这里面会注册几个比较重要的BeanPostProcessor //AutowiredAnnotationBeanPostProcessor,ConfigurationClassPostProcessor,CommonAnnotationBeanPostProcessor this.registerComponents(parserContext.getReaderContext(), beanDefinitions, element); return null; }
ComponentScanBeanDefinitionParser - 60 - N49 protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { //使用默认的过滤器 boolean useDefaultFilters = true; if (element.hasAttribute("use-default-filters")) { useDefaultFilters = Boolean.valueOf(element.getAttribute("use-default-filters")); } //N50 创建注解扫描器 这里使用默认的过滤器useDefaultFilters=true ClassPathBeanDefinitionScanner scanner = this.createScanner(parserContext.getReaderContext(), useDefaultFilters); scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); if (element.hasAttribute("resource-pattern")) { scanner.setResourcePattern(element.getAttribute("resource-pattern")); } try { this.parseBeanNameGenerator(element, scanner); } catch (Exception var7) { parserContext.getReaderContext().error(var7.getMessage(), parserContext.extractSource(element), var7.getCause()); } try { this.parseScope(element, scanner); } catch (Exception var6) { parserContext.getReaderContext().error(var6.getMessage(), parserContext.extractSource(element), var6.getCause()); } this.parseTypeFilters(element, scanner, parserContext); return scanner; }
ComponentScanBeanDefinitionParser - 89 - N50 protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) { //N51 进入创建扫描器的构造函数 return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters, readerContext.getEnvironment(), readerContext.getResourceLoader()); }
ClassPathBeanDefinitionScanner - 48 - N51 public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters, Environment environment, @Nullable ResourceLoader resourceLoader) { this.beanDefinitionDefaults = new BeanDefinitionDefaults(); this.beanNameGenerator = new AnnotationBeanNameGenerator(); this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); this.includeAnnotationConfig = true; Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); this.registry = registry; if (useDefaultFilters) { //N52 这里注册默认过滤器到扫描器中 this.registerDefaultFilters(); } this.setEnvironment(environment); this.setResourceLoader(resourceLoader); }
ClassPathScanningCandidateComponentProvider - 111 - N52 protected void registerDefaultFilters() { //在这个类中我们会发现只添加了component到过滤器中,但是我们在使用的时候,spring会为我们扫描除了@component注解外的如@controller@service等 //注解,这个原因是因为这些注解上面都继承自@component注解,这些注解在声明时都添加了@component,所以我们能扫描到@component注解及其子注解 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false)); this.logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException var4) { } try { this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false)); this.logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException var3) { } }
ClassPathBeanDefinitionScanner - 105 - N53 protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet(); String[] var3 = basePackages; int var4 = basePackages.length; for(int var5 = 0; var5 < var4; ++var5) { String basePackage = var3[var5]; //N54 这里是获取到所有符合条件的类(也就是包含过滤器中的注解的类)并封装成beanDefinition,只是这些bd还未赋值到各个属性中 Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage); Iterator var8 = candidates.iterator(); //遍历符合条件的beanDefinition集合Set,然后从bd中拿出metadata分别赋值到bd中各个属性 while(var8.hasNext()) { BeanDefinition candidate = (BeanDefinition)var8.next(); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); //设置scope属性 candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //因为前面只是在bd中有个metadata,还没有赋值到bd各个属性中,所以这里对bd各个属性进行默认赋值 this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //N61 支持了@Lazy @DependOn注解 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate); } if (this.checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //N63 将beanDefinition注册到map和list容器中 this.registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
ClassPathScanningCandidateComponentProvider - 178 - N54 public Set<BeanDefinition> findCandidateComponents(String basePackage) { //N55 进入到scanCandidateComponents return this.componentsIndex != null && this.indexSupportsIncludeFilters() ? this.addCandidateComponentsFromIndex(this.componentsIndex, basePackage) : this.scanCandidateComponents(basePackage); }
ClassPathScanningCandidateComponentProvider - 267 - N55 private Set<BeanDefinition> scanCandidateComponents(String basePackage) { LinkedHashSet candidates = new LinkedHashSet(); try { String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern; //N56 递归寻找文件 Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = this.logger.isTraceEnabled(); boolean debugEnabled = this.logger.isDebugEnabled(); Resource[] var7 = resources; int var8 = resources.length; //这里找到了base-package属性(N46中的base-package="com.kaka")路径中的所有class文件并遍历 for(int var9 = 0; var9 < var8; ++var9) { Resource resource = var7[var9]; if (traceEnabled) { this.logger.trace("Scanning " + resource); } //判断文件可读性 if (resource.isReadable()) { try { //N57 包装了类的基本信息的对象 MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource); //N60 通过类的基本信息对象可以判断类上是否有包含includeFilters注解 if (this.isCandidateComponent(metadataReader)) { //进入这里则说明类上含有includeFilters中的注解,则需要spring实例化,所以要封装成BeanDefinition //这里封装成ScannedGenericBeanDefinition类,将metadataReader中的annotationMetadata属性赋值给 //ScannedGenericBeanDefinition类中的metadata属性,这个属性就是记录了类信息的对象, //此时还未赋值给bd中各属性,只是在bd中用ScannedGenericBeanDefinition类对象存储 ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) { if (debugEnabled) { this.logger.debug("Identified candidate component class: " + resource); } candidates.add(sbd); } else if (debugEnabled) { this.logger.debug("Ignored because not a concrete top-level class: " + resource); } } else if (traceEnabled) { this.logger.trace("Ignored because not matching any filter: " + resource); } } catch (Throwable var13) { throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13); } } else if (traceEnabled) { this.logger.trace("Ignored because not readable: " + resource); } } return candidates; } catch (IOException var14) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14); } }
PathMatchingResourcePatternResolver - 88 - N56 public Resource[] getResources(String locationPattern) throws IOException { //这个类主要就是找到路径下的所有.class尾缀文件,就是一个匹配过程,这里不深究 Assert.notNull(locationPattern, "Location pattern must not be null"); if (locationPattern.startsWith("classpath*:")) { return this.getPathMatcher().isPattern(locationPattern.substring("classpath*:".length())) ? this.findPathMatchingResources(locationPattern) : this.findAllClassPathResources(locationPattern.substring("classpath*:".length())); } else { int prefixEnd = locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 : locationPattern.indexOf(58) + 1; return this.getPathMatcher().isPattern(locationPattern.substring(prefixEnd)) ? this.findPathMatchingResources(locationPattern) : new Resource[]{this.getResourceLoader().getResource(locationPattern)}; } }
CachingMetadataReaderFactory - 61 - N57 public MetadataReader getMetadataReader(Resource resource) throws IOException { if (this.metadataReaderCache instanceof ConcurrentMap) { MetadataReader metadataReader = (MetadataReader)this.metadataReaderCache.get(resource); if (metadataReader == null) { metadataReader = super.getMetadataReader(resource); this.metadataReaderCache.put(resource, metadataReader); } return metadataReader; } else if (this.metadataReaderCache != null) { synchronized(this.metadataReaderCache) { MetadataReader metadataReader = (MetadataReader)this.metadataReaderCache.get(resource); if (metadataReader == null) { metadataReader = super.getMetadataReader(resource); this.metadataReaderCache.put(resource, metadataReader); } return metadataReader; } } else { //N58 通过父类方法包装class文件信息为MetadataReader对象 return super.getMetadataReader(resource); } }
SimpleMetadataReaderFactory - 55 - N58 public MetadataReader getMetadataReader(Resource resource) throws IOException { //N59 SimpleMetadataReader是MetadataReader的子类 return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader()); }
SimpleMetadataReader - 22 - N59 SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException { //先获取文件流,Resource是InputStreamSource的子类,调用getInputStream()就可以获得文件流 BufferedInputStream is = new BufferedInputStream(resource.getInputStream()); ClassReader classReader; try { classReader = new ClassReader(is); } catch (IllegalArgumentException var9) { throw new NestedIOException("ASM ClassReader failed to parse class file - probably due to a new Java class file version that isn't supported yet: " + resource, var9); } finally { is.close(); } AnnotationMetadataReadingVisitor visitor = new AnnotationMetadataReadingVisitor(classLoader); //AnnotationMetadataReadingVisitor是ClassMetadata和AnnotationMetadata的子类,这个visitor对象就是存储了文件类信息的对象 classReader.accept(visitor, 2); this.annotationMetadata = visitor; this.classMetadata = visitor; this.resource = resource; }
ClassPathScanningCandidateComponentProvider - 321 - N60 //在这个类会获取到excludeFilters和includeFilters两个过滤器来匹配这个类信息中的注解信息, //如果类信息中注解信息没有excludeFilters中的注解且有includeFilters中的注解,则视为匹配成功 protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { Iterator var2 = this.excludeFilters.iterator(); TypeFilter tf; do { if (!var2.hasNext()) { var2 = this.includeFilters.iterator(); do { if (!var2.hasNext()) { //走到这里就是两个过滤器都没有,则表示匹配失败 return false; } tf = (TypeFilter)var2.next(); } while(!tf.match(metadataReader, this.getMetadataReaderFactory())); //走到这里就是没有excludeFilters中的注解且有includeFilters中的注解,则表示匹配成功 return this.isConditionMatch(metadataReader); } tf = (TypeFilter)var2.next(); } while(!tf.match(metadataReader, this.getMetadataReaderFactory())); //走到这里说明存在excludeFilters中的注解,所以匹配失败 return false; }
AnnotationConfigUtils - 125 - N61 public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { //N62 processCommonDefinitionAnnotations(abd, abd.getMetadata()); }
AnnotationConfigUtils - 129 - N62 static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); //对@Lazy注解的支持 if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } else if (abd.getMetadata() != metadata) { lazy = attributesFor(abd.getMetadata(), (Class)Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } } //@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")); } 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")); } }
ClassPathBeanDefinitionScanner - 149 - N63 protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) { //N28 这里注册和默认标签注册都是一样的,都是加入到map和list两个容器中 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry); }
ComponentScanBeanDefinitionParser - 93 - N64 protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) { Object source = readerContext.extractSource(element); CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source); Iterator var6 = beanDefinitions.iterator(); while(var6.hasNext()) { BeanDefinitionHolder beanDefHolder = (BeanDefinitionHolder)var6.next(); compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder)); } boolean annotationConfig = true; if (element.hasAttribute("annotation-config")) { annotationConfig = Boolean.valueOf(element.getAttribute("annotation-config")); } if (annotationConfig) { //N65 这里面会注册几个比较重要的BeanPostProcessor,请务必记住这个点,后面会提到 Set<BeanDefinitionHolder> processorDefinitions = AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source); Iterator var8 = processorDefinitions.iterator(); while(var8.hasNext()) { BeanDefinitionHolder processorDefinition = (BeanDefinitionHolder)var8.next(); compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition)); } } readerContext.fireComponentRegistered(compositeDef); }
AnnotationConfigUtils - 50 - N65 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); //这里注册ConfigurationClassPostProcessor,这个类作用很大,完成了@Bean的部分工作,还完成了注解方式启动spring的工作,后续会详细讲解这个类。 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } //这里注册AutowiredAnnotationBeanPostProcessor 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)); } //这里注册CommonAnnotationBeanPostProcessor // 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)); } // 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)); } 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)); } 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; }
到这里也就基本完成了所有需要实例化的Bean封装成bd的步骤,也就是完成了N2中refresh方法中的obtainFreshBeanFactory方法。下一小节会回到N2中的refresh方法中继续讲解。
这篇关于Spring源码解析(二)-自定义标签的解析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南