前言
本文转自“天河聊技术”微信公众号
本次继续介绍@Configuration、@Import、 bean定义解析
正文
进入这个方法
org.springframework.context.annotation.ConfigurationClassParser#processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, CollectionimportCandidates, boolean checkForCircularImports) throws IOException { if (importCandidates.isEmpty()) { return; } if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { for (SourceClass candidate : importCandidates) { if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class candidateClass = candidate.loadClass();// 初始化@Import处理器 ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else {// 解析@Configuration元注解信息选择要导入的类的信息 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection importSourceClasses = asSourceClasses(importClassNames); processImports(configClass, currentSourceClass, importSourceClasses, false); } } 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 = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> // process it as an @Configuration class this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); processConfigurationClass(candidate.asConfigClass(configClass)); } } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } finally { this.importStack.pop(); } } }
找到这行代码
// 递归调用 processImports(configClass, currentSourceClass, importSourceClasses, false);
递归调用 processConfigurationClass(candidate.asConfigClass(configClass));
找到这个方法org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass这一行代码
// Process any @ImportResource annotations 解析@ImportResource的属性值AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
// 资源路径是数组的形式 String[] resources = importResource.getStringArray("locations");
找到这行代码
// Process individual @Bean methods 解析带有@Bean的方法源数据SetbeanMethods = retrieveBeanMethodMetadata(sourceClass);
进入这个方法
org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata
检索@Bean注解的方法源数据
private SetretrieveBeanMethodMetadata(SourceClass sourceClass) { AnnotationMetadata original = sourceClass.getMetadata();// 从源数据中获取@Bean的方法源数据 Set beanMethods = original.getAnnotatedMethods(Bean.class.getName()); if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) { // Try reading the class file via ASM for deterministic declaration order... // Unfortunately, the JVM's standard reflection returns methods in arbitrary // order, even between different runs of the same application on the same JVM. try { AnnotationMetadata asm = this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata(); Set asmMethods = asm.getAnnotatedMethods(Bean.class.getName()); if (asmMethods.size() >= beanMethods.size()) { Set selectedMethods = new LinkedHashSet<>(asmMethods.size()); for (MethodMetadata asmMethod : asmMethods) { for (MethodMetadata beanMethod : beanMethods) { if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) { selectedMethods.add(beanMethod); break; } } } if (selectedMethods.size() == beanMethods.size()) { // All reflection-detected methods found in ASM method set -> proceed beanMethods = selectedMethods; } } } catch (IOException ex) { logger.debug("Failed to read class file via ASM for determining @Bean method order", ex); // No worries, let's continue with the reflection metadata we started with... } } return beanMethods; }
返回到这个方法
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions这行代码
// 加载bean定义 this.reader.loadBeanDefinitions(configClasses);
进入这个方法
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { if (trackedConditionEvaluator.shouldSkip(configClass)) { String beanName = configClass.getBeanName(); if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; } if (configClass.isImported()) {// 将@Configuration的类本身注册为bean定义 registerBeanDefinitionForImportedConfigurationClass(configClass); } for (BeanMethod beanMethod : configClass.getBeanMethods()) {// 根据bean的method加载bean定义 loadBeanDefinitionsForBeanMethod(beanMethod); } loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
进入这个方法
// 将@Configuration的类本身注册为bean定义 registerBeanDefinitionForImportedConfigurationClass(configClass);
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { AnnotationMetadata metadata = configClass.getMetadata(); AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);// 解析scope的源数据 ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName());// 生成beanName String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);// 解析一般的bean定义属性 AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// bean定义注册 this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition()); configClass.setBeanName(configBeanName); if (logger.isDebugEnabled()) { logger.debug("Registered bean definition for imported class '" + configBeanName + "'"); } }
返回到org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass这个方法的这行代码
// 将@Configuration的类本身注册为bean定义 registerBeanDefinitionForImportedConfigurationClass(configClass);
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { AnnotationMetadata metadata = configClass.getMetadata(); AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);// 解析scope的源数据 ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName());// 生成beanName String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);// 解析一般的bean定义属性 AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// bean定义注册 this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition()); configClass.setBeanName(configBeanName); if (logger.isDebugEnabled()) { logger.debug("Registered bean definition for imported class '" + configBeanName + "'"); } }
返回到到这个方法org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass的这一行代码
for (BeanMethod beanMethod : configClass.getBeanMethods()) {// 根据bean的method加载bean定义 loadBeanDefinitionsForBeanMethod(beanMethod); }
进入这个方法
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); // Do we need to mark the bean as skipped by its condition? if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; } if (configClass.skippedBeanMethods.contains(methodName)) { return; }// 从源数据中获取@Bean的属性值 AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); Assert.state(bean != null, "No @Bean annotation attributes"); // Consider name and any aliases Listnames = new ArrayList<>(Arrays.asList(bean.getStringArray("name"))); String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden 注册别名 for (String alias : names) { this.registry.registerAlias(beanName, alias); } // Has this effectively been overridden before (e.g. via XML)? 这是否已经被有效地覆盖了(例如通过XML)? if (isOverriddenByExistingDefinition(beanMethod, beanName)) { if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) { throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(), beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!"); } return; } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) { // static @Bean method beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(methodName); } else { // instance @Bean method beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(methodName); }// 设置自动装配模式为构造方法装配 beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);// 默认Required属性值是true beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);// 解析一般的bean定义属性值 AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);// 解析autowire属性 Autowire autowire = bean.getEnum("autowire"); if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); }// 解析initMethod初始化方法 String initMethodName = bean.getString("initMethod"); if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName); }// 解析destroyMethod方法 String destroyMethodName = bean.getString("destroyMethod"); beanDef.setDestroyMethodName(destroyMethodName); // Consider scoping 默认scope属性值是no ScopedProxyMode proxyMode = ScopedProxyMode.NO;// 获取@Scope的值 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (attributes != null) { beanDef.setScope(attributes.getString("value")); proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } // Replace the original bean definition with the target one, if necessary 如果需要,将原始bean定义替换为目标函数。 BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) {// cglib动态代理 BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); } if (logger.isDebugEnabled()) { logger.debug(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName)); }// 注册bean定义 this.registry.registerBeanDefinition(beanName, beanDefToRegister); }
返回到这个方法org.springframework.context.support.AbstractApplicationContext#refresh
这一行代码
invokeBeanFactoryPostProcessors(beanFactory);
本次解析到这里结束。
最后
本次介绍到这里,以上内容仅供参考。