栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring底层扫描过程(@Component)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring底层扫描过程(@Component)


一、ClassPathBeanDefinitionScanner#doScan

    protected Set doScan(String... basePackages) {
        Assert.notEmpty(basePackages, "At least one base package must be specified");
        Set beanDefinitions = new LinkedHashSet();
        String[] var3 = basePackages;
        int var4 = basePackages.length;
        //扫描@ComponentScan包设置扫描包路径
        for(int var5 = 0; var5 < var4; ++var5) {
            String basePackage = var3[var5];
            //获取候选的BeanDefinition此时
            Set candidates = this.findCandidateComponents(basePackage);
            Iterator var8 = candidates.iterator();

            while(var8.hasNext()) {
                BeanDefinition candidate = (BeanDefinition)var8.next();
                ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                candidate.setScope(scopeMetadata.getScopeName());
                String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                if (candidate instanceof AbstractBeanDefinition) {
                //为beanDefinition设置InitMethod、DestroyMethod、LazyInit等属性
                    this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
                }

                if (candidate instanceof AnnotatedBeanDefinition) {
                 //设置@Lazy @Primary @DependsOn  @Role @Description属性
                 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
                }
				//检查容器中是否存在相同名称的beanDefinition,存在则报错(特殊情况,spring存在注册同一个配置类,则beandefinition不会注册)
                if (this.checkCandidate(beanName, candidate)) {
                    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                    beanDefinitions.add(definitionHolder);
                    this.registerBeanDefinition(definitionHolder, this.registry);
                }
            }
        }

        return beanDefinitions;
    }

二、获取候选的beandefinition,this.findCandidateComponents(basePackage)

public Set findCandidateComponents(String basePackage) {
        LinkedHashSet candidates = new LinkedHashSet();

        try {
            String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;
            //包下class对象都会解析成对应的resource对象文件对象
            Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
            boolean traceEnabled = this.logger.isTraceEnabled();
            boolean debugEnabled = this.logger.isDebugEnabled();
            Resource[] var7 = resources;
            int var8 = resources.length;
             //遍历所有文件对象数组
            for(int var9 = 0; var9 < var8; ++var9) {
                Resource resource = var7[var9];
                if (traceEnabled) {
                    this.logger.trace("Scanning " + resource);
                }

                if (resource.isReadable()) {
                    try {
                    //利用ASM技术把文件对象解析成元数据信息
                        MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
                        //解析是否包含Component注解,以及剔除excludeFilters配置的,includeFilters匹配则成功(new AnnotationTypeFilter(Component.class)),匹配通过继续筛选是否有Condition条件
                        if (this.isCandidateComponent(metadataReader)) {
                            ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                            sbd.setResource(resource);
                            sbd.setSource(resource);
                            //判断当前对象是否顶级、静态内部类对象,非抽象类、非接口对象,若为抽象类(包含@Lookup注解)也通过;总结:顶级类、非接口抽象类、抽象类(必须包含@Lookup注解)
                            if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {
                                if (debugEnabled) {
                                    this.logger.debug("Identified candidate component class: " + resource);
                                }
                            //满足以上条件才能成为候选beanDefinition即真正的beandefinition
                                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);
        }
    }

三、this.isCandidateComponent

    protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
       //@ComponentScan中配置剔除条件过滤器
        Iterator var2 = this.excludeFilters.iterator();

        TypeFilter tf;
        do {
            if (!var2.hasNext()) {
            //@ComponentScan中满足这些条件过滤器则通过,spring内置一个 this.includeFilters.add(new AnnotationTypeFilter(Component.class));
                var2 = this.includeFilters.iterator();

                do {
                    if (!var2.hasNext()) {
                        return false;
                    }

                    tf = (TypeFilter)var2.next();
                } while(!tf.match(metadataReader, this.metadataReaderFactory));
                //以上条件都满足看当前bean是否有@Condition注解上设置的条件继续看是否满足条件
                return this.isConditionMatch(metadataReader);
            }

            tf = (TypeFilter)var2.next();
        } while(!tf.match(metadataReader, this.metadataReaderFactory));

        return false;
    }

四、上面筛选出@Component的beandefinition此时还不能是真正的beandefition
必须满足一下条件才能成为真正的beandefinition
this.isCandidateComponent((AnnotatedBeanDefinition)sbd)

    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        AnnotationMetadata metadata = beanDefinition.getMetadata();
        //1、顶级类、静态内部类  2、非接口、非抽象类  3、抽象类(有@Lookup注解)
        return metadata.isIndependent() && (metadata.isConcrete() || metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()));
    }

五、总结

1、扫描@ComponentScan配置扫描包路径
2、扫描到class封装成Resource文件对象
3、遍历Resource数组对象,把Resource对象ASM技术封装成MetadataReader
4、MetadataReader对其进行筛选(配置的过滤器,默认 this.includeFilters.add(new AnnotationTypeFilter(Component.class))会去过滤Component注解的类,筛选类上是否有@Condtition注解的条件
5、a、顶级类、静态内部类、b、非接口、非抽象类、c、抽象类(包含@Lookup注解的类)满足以上45中才能BeanDefinition
6、为BeanDefinition设置@Lazy @Primary @DependsOn @Role @Description属性、设置InitMethod、DestroyMethod、LazyInit等属性
7、把BeanDefinition添加到map中,beanDefinitions.add(definitionHolder);

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/973675.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号