Spring源码分析之`BeanFactoryPostProcessor`调用过程 (2)

ConfigurationClassUtils.checkConfigurationClassCandidate中的摘取片段

//检查是否有标识@Configuration Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName()); if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) { //设置配置属性值为full beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } //检查是否包含@Component @ComponentScan @Import @ImportResource @Bean else if (config != null || isConfigurationCandidate(metadata)) { //设置配置属性值为lite beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else { return false; } 配置类解析流程(parser.parse(candidates)) public void parse(Set<BeanDefinitionHolder> configCandidates) { for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); //配置类的beanDefinition为AnnotatedGenericBeanDefinition,true if (bd instanceof AnnotatedBeanDefinition) { //传入配置类的元数据与beanName parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } } } protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER); } processConfigurationClass protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException { SourceClass sourceClass = asSourceClass(configClass, filter); do { //解析配置类,这里可能返回配置类的父类,需要继续处理 sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter); } while (sourceClass != null); //将配置类放入map中 this.configurationClasses.put(configClass, configClass); } doProcessConfigurationClass //@Configuration 本身也是 @Component的组合注解 if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // 处理内置类,如果内置类也是个配置类,递归处理内置类 processMemberClasses(configClass, sourceClass, filter); } 处理@ComponentScan // Process any @ComponentScan annotations // 找出配置类上的@ComponentScan注解属性 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); for (AnnotationAttributes componentScan : componentScans) { //将@ComponentScan引入的所有类扫描成BeanDefinition并注册到容器中 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); //这里循环是为了判断扫描出来的beanDefinition是否是配置类,如果是配置类的话需要递归解析 for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); //这里是必然为true, 能被扫描出来的必然有@Component注解,而@Component注解为lite配置类 //这里主要是为了在检查的同时设置一下full或者lite的类型 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { //配置类就继续递归解析 parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } this.componentScanParser.parse public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { //重新new了一个classpath的bean定义扫描器,没用我们最开始创建的 // 这里添加了一个默认的过滤器,过滤@Component注解的 ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); //添加自己配置的过滤器 for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addIncludeFilter(typeFilter); } } for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addExcludeFilter(typeFilter); } } //如果配置的为懒加载,则扫描出来的所有BeanDefinition都默认为懒加载的 boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } //将配置的basePackages中所有的包路径放到set集合中,保证最终所有的包路径唯一 Set<String> basePackages = new LinkedHashSet<>(); String[] basePackagesArray = componentScan.getStringArray("basePackages"); for (String pkg : basePackagesArray) { String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); Collections.addAll(basePackages, tokenized); } //添加一个排除过滤器,排除该配置类 scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { @Override protected boolean matchClassName(String className) { return declaringClass.equals(className); } }); //开始扫描 return scanner.doScan(StringUtils.toStringArray(basePackages)); } 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) { //找到所有候选的bean -> 默认过滤器为过滤标识了@Component注解的class Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //设置默认值,比如上一个方法刚刚设置的是否懒加载 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //解析beanClass的所有注解填充到beanDefinition中,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //检查之前是否注册过,未注册返回true if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); beanDefinitions.add(definitionHolder); //将beanDefinition注册到容器中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; } 寻找候选组件#findCandidateComponents public Set<BeanDefinition> findCandidateComponents(String basePackage) { return scanCandidateComponents(basePackage); } private Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); //将类路径替换成绝对路径 String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + 'http://www.likecs.com/' + this.resourcePattern; //找出该路径下的所有类资源 Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); //调用刚刚配置的过滤器进行匹配, //默认过滤器逻辑:是否标识了@Component注解(包括组合的,如@Service) if (isCandidateComponent(metadataReader)) { //通过扫描方式创建的BeanDefintion为ScannedGenericBeanDefinition ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setSource(resource); //不是接口和抽象类,或者是抽象类但标识了@Lookup if (isCandidateComponent(sbd)) { //将beanDefinition存到集合中 candidates.add(sbd); } } } } return candidates; } 处理@Import processImports(configClass, sourceClass, getImports(sourceClass), filter, true); private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) { //importCandidates为@Import中的value数组 for (SourceClass candidate : importCandidates) { if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class<?> candidateClass = candidate.loadClass(); //实例化我们写的实现ImportSelector接口的类 ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class, this.environment, this.resourceLoader, this.registry); //调用selectImports方法返回我们需要注入到容器中bean数组 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); //转为SourceClass集合 Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter); //再次递归调用本方法,如果我们返回的数组是一些没有实现Import相关接口的类, //就会走到最后的else逻辑,当成配置类处理 processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false); } //这里就走实现ImportBeanDefinitionRegistrar接口的逻辑 else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { // Candidate class is an ImportBeanDefinitionRegistrar -> // delegate to it to register additional bean definitions Class<?> candidateClass = candidate.loadClass(); //实例化 ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class, this.environment, this.resourceLoader, this.registry); //这里先把Registrar放到配置类的importBeanDefinitionRegistrars属性中,最后解析完调用loadBeanDefinition进行处理 configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { //普通的bean当做配置类处理 processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter); } } } 处理@Bean // 将配置类中@Bean的方法解析成方法元数据放到配置类中 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); }

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

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