曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析) (2)

MetadataReader这个接口,也是以后的重点,这里概览一下:

/** * 通过asm,获取类的元数据,包括注解数据 * Simple facade for accessing class metadata, * as read by an ASM {@link org.springframework.asm.ClassReader}. * * @author Juergen Hoeller * @since 2.5 */ public interface MetadataReader { /** * Return the resource reference for the class file. */ Resource getResource(); /** * 获取Class的相关信息 * Read basic class metadata for the underlying class. */ ClassMetadata getClassMetadata(); /** * 这个就叼了,获取Class上的注解信息 * Read full annotation metadata for the underlying class, * including metadata for annotated methods. */ AnnotationMetadata getAnnotationMetadata(); }

有人可能觉得没啥用,通过java反射也能获取;但这里的和java反射的方式不冲突,这个是通过asm框架来获取,效率会更高(效率比反射低的话,spring团队为啥不用反射呢,对吧?)

回到前面的metadataReader的factory接口,其实现类就两个,我们这次分析的源码,用了CachingMetadataReaderFactory:

曹工说Spring Boot源码(12)-- Spring解析xml文件,到底从中得到了什么(context:component-scan完整解析)

子类ClassPathBeanDefinitionScanner中的字段 // beanDefinition注册中心,拿到beanDefinition后就往这里面放 private final BeanDefinitionRegistry registry; // 默认的beanDefinition配置,和xml里<beans>元素里的属性是对应的 private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults(); // 自动注入时,候选bean需要满足的pattern private String[] autowireCandidatePatterns; // beanName 生成器 private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator(); // 不是很了解,skip private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver(); // 要不要激活 context:annotation-config元素的作用;具体可看本博文往前的两篇 private boolean includeAnnotationConfig = true;

其实,把前面父类,和现在这个子类的字段,合起来看,也就那么回事吧,主要是些配置数据,把xml里用户的配置给存起来了。

具体配置过程解析 org.springframework.context.annotation.ComponentScanBeanDefinitionParser#configureScanner protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) { XmlReaderContext readerContext = parserContext.getReaderContext(); // 是否使用默认的filter,默认filter,只解析component等官方注解 boolean useDefaultFilters = true; if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) { useDefaultFilters = Boolean.valueOf(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)); } // 创建scanner ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters); // 设置默认的东西 scanner.setResourceLoader(readerContext.getResourceLoader()); scanner.setEnvironment(parserContext.getDelegate().getEnvironment()); // 设置默认的东西,包括了beanDefinition的默认属性,这个是可以从外边传进来的 scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults()); //这个也是外边来的,xml里没这个属性 scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns()); if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) { // 这个是从xml元素来的 scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE)); } try { // 这个也是xml属性来的 parseBeanNameGenerator(element, scanner); } catch (Exception ex) { readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause()); } try { // 这个也是xml属性来的 parseScope(element, scanner); } catch (Exception ex) { readerContext.error(ex.getMessage(), readerContext.extractSource(element), ex.getCause()); } // 这个也是xml属性来的,主要是解析include/exclude filter parseTypeFilters(element, scanner, readerContext, parserContext); return scanner; }

其中,有两个点值得细说:

默认的filter

ClassPathBeanDefinitionScanner scanner = createScanner(readerContext, useDefaultFilters); 一路简单跳转后,进入到: public ClassPathScanningCandidateComponentProvider(boolean useDefaultFilters, Environment environment) { if (useDefaultFilters) { // 注册默认的filter registerDefaultFilters(); } this.environment = environment; } // 注册3个注解类型的fitler,分别对应了Component/javax.annotation.ManagedBean/javax.inject.Named 这几个注解 protected void registerDefaultFilters() { /** * 默认扫描Component注解 */ this.includeFilters.add(new AnnotationTypeFilter(Component.class)); ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) cl.loadClass("javax.annotation.ManagedBean")), false)); } try { this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) cl.loadClass("javax.inject.Named")), false)); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsjxd.html