基于Spring注解的上下文初始化过程源码解析(二…
2019-08-16 12:00:02来源:博客园 阅读 ()
基于Spring注解的上下文初始化过程源码解析(二)
上一篇看完了register方法的代码,继续跟后面代码
后面执行refresh方法,代码清单如下:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. /** * 准备刷新上下文,设置其启动日期和活动标志以及执行属性源的任何初始化 */ prepareRefresh(); // Tell the subclass to refresh the internal bean factory. /** * 通知子类刷新内部的 bean 工厂 * 得到创建的 DefaultListableBeanFactory 工厂 * DefaultListableBeanFactory 实现了 ConfigurableListableBeanFactory * 接下来对工厂进行初始化 */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. /** * 配置工厂的标准上下文特征 */ prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. /** * 允许在上下文子类中对 bean 工厂进行后置处理 * * 当前版本的 Spring 代码中没有任何作用,可能是 Spring 为了在后面的版本中方便扩展 */ postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. /** * 第一重要的方法 * * 在上下文中调用工厂处理器方法,注册为 bean * 在 Spring 的环境中去执行已经被注册的 BeanFactoryPostProcessors * 注册自定义的 BeanFactoryPostProcessors 和 Spring 内部定义的 BeanFactoryPostProcessors * * 比较重要的一个是 ConfigurationClassPostProcessor * 实例化 AnnotationConfigApplicationContext 时初始化了一个 AnnotatedBeanDefinitionReader * AnnotatedBeanDefinitionReader 的构造方法中将 ConfigurationClassPostProcessor 注册到 BeanDefinition 中 */ invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册 BeanPostProcessor,Spring AOP 就是在这里进行注册的 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 初始化此上下文的消息源 initMessageSource(); // Initialize event multicaster for this context. // 初始化应用事件广播器【SpringBoot 的启动源码中与该方法有很大关系】 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 在特定的上下文子类中初始化其他特殊 bean // 当前版本中也是什么都没做 onRefresh(); // Check for listener beans and register them. // 检查监听器 bean 并注册它们 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. /** * 第二重要的方法 * * 实例化所有剩余(非延迟初始化)单例。 */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. /** * 最后一步:发布相应的事件 */ finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. /** * 摧毁已经创建的单例 Bean 以避免悬空资源 */ destroyBeans(); // Reset 'active' flag. /** * 重置 active 属性值 */ cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
这里就只讨论两个比较重要的方法,分别是 invokeBeanFactoryPostProcessors 方法和 finishBeanFactoryInitialization 方法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { /** * 如果有的话,首先调用 BeanDefinitionRegistryPostProcessors */ Set<String> processedBeans = new HashSet<>(); /** * 如果 beanFactory 是 BeanDefinitionRegistry * * beanFactory 是 DefaultListableBeanFactory * DefaultListableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry */ if (beanFactory instanceof BeanDefinitionRegistry) { // 转换成 BeanDefinition 注册器 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // Bean 工厂后置处理器集合 // 存放手动添加的 BeanFactoryPostProcessor List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); // BeanDefinition 注册器后置处理器集合 /** * BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor * 存放所有需要注册的 BeanDefinitionRegistryPostProcessor */ List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 循环遍历手动添加的 BeanFactoryPostProcessor for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // 外部扩展的 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 调用 postProcessBeanDefinitionRegistry 方法,不是回调 registryProcessor.postProcessBeanDefinitionRegistry(registry); // 存入集合 registryProcessors.add(registryProcessor); } // Spring 内部的 else { // 存入集合 regularPostProcessors.add(postProcessor); } } /** * 需要保留所有未初始化的常规 bean,以使 bean 工厂后置处理器适用于这些 bean * 在实现 PriorityOrdered,Ordered 和其余的 BeanDefinitionRegistryPostProcessors 之间分开 * * 放 Spring 内部的 BeanDefinitionRegistryPostProcessor */ List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); /** * 获取 BeanDefinitionRegistryPostProcessor bean 名称 * BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子类 * * 此时至少包含了一个 ConfigurationClassPostProcessor * class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor * 名称为 internalConfigurationAnnotationProcessor */ String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); /** * ConfigurationClassPostProcessor 最重要的类 */ for (String ppName : postProcessorNames) { /** * 首先,调用实现 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors */ if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 实例化该 bean,并添加到集合中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 添加到集合中 processedBeans.add(ppName); } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 合并 registryProcessors.addAll(currentRegistryProcessors); /** * 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法 * * 集合中的元素包含 ConfigurationClassPostProcessor */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 执行完成,清空集合数据 // 至少清除包含的 ConfigurationClassPostProcessor currentRegistryProcessors.clear(); // 获取 BeanDefinitionRegistryPostProcessor bean 名称 // 下面的代码理论上不会执行,只是 Spring 确保初始化过程中没有新的类被添加进来 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { /** * 接下来,调用实现 Ordered 的 BeanDefinitionRegistryPostProcessors * * 不在 processedBeans 中且实现了 Ordered 的 BeanDefinitionRegistryPostProcessors */ if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // 实例化该 bean,并添加到集合中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 添加到集合中 processedBeans.add(ppName); } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 合并 registryProcessors.addAll(currentRegistryProcessors); /** * 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 执行完成,清空集合数据 currentRegistryProcessors.clear(); /** * 最后,调用所有其他 BeanDefinitionRegistryPostProcessors * 直到不再出现其他 BeanDefinitionRegistryPostProcessors */ boolean reiterate = true; while (reiterate) { reiterate = false; // 获取 BeanDefinitionRegistryPostProcessor 名称 postProcessorNames = beanFactory.getBeanNamesForType( BeanDefinitionRegistryPostProcessor.class, true, false ); for (String ppName : postProcessorNames) { // 执行剩下的 BeanDefinitionRegistryPostProcessors if (!processedBeans.contains(ppName)) { // 实例化该 bean,并添加到集合中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 合并 registryProcessors.addAll(currentRegistryProcessors); /** * 调用 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry 方法 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 执行完成,清空集合数据 currentRegistryProcessors.clear(); } /** * 刚才执行完 ConfigurationClassPostProcessor 的回调 * ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor * 现在调用到目前为止处理的所有 BeanFactoryPostProcessor#postProcessBeanFactory 方法的回调 */ invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. /** * 调用在上下文实例中注册的工厂处理器 */ invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } /** * 获取 BeanFactoryPostProcessor 名称 * 此时至少有两个元素: * org.springframework.context.annotation.internalConfigurationAnnotationProcessor * org.springframework.context.event.internalEventListenerProcessor * * 需要保留所有未初始化的常规 bean,以使 bean 工厂后处理器适用于这些 bean */ String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); /** * 分隔实现了 PriorityOrdered,Ordered 和其余的 BeanFactoryPostProcessors */ List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { // 处理过则跳过 if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } // 实现了 PriorityOrdered else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } // 实现了 Ordered else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } // 普通类 else { // org.springframework.context.event.internalEventListenerProcessor 是普通类 nonOrderedPostProcessorNames.add(ppName); } } /** * 首先,调用实现 PriorityOrdered 的 BeanFactoryPostProcessors */ // 排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); /** * 接下来,调用实现 Ordered 的 BeanFactoryPostProcessors */ List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); /** * 最后,调用所有其他 BeanFactoryPostProcessors */ List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 调用 BeanFactoryPostProcessor#postProcessBeanFactory 方法 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
/** * 清除缓存的合并 bean 定义,因为后处理器可能已经修改了原始元数据,例如,替换值中的占位符 */ beanFactory.clearMetadataCache(); }
这里的 invokeBeanDefinitionRegistryPostProcessors 方法比较重要,跟进去后最后调用的是 processConfigBeanDefinitions 方法。
Spring将处理 BeanDefinition 的工作委托给了 ConfigurationClassPostProcessor 这个辅助类来完成
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); // 获取容器中注册的所有 BeanDefinition 名称 /** * AnnotatedBeanDefinitionReader 扫描的 6 个 * 和初始化 Spring 上下文环境时传入的一个配置类 */ String[] candidateNames = registry.getBeanDefinitionNames(); /** * 遍历获取需要解析的类 */ for (String beanName : candidateNames) { // 获取 BeanDefinition BeanDefinition beanDef = registry.getBeanDefinition(beanName); /** * 如果 BeanDefinition 中的 configurationClass 属性为 full 或者 lite,则表示已经处理过了,直接跳过 */ if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 否则判断是否是 @Configuration 注解配置类,加了则通过校验,没加再判断是否加了以下注解 /** * 如果加了 @Configuration 注解,会在后面再解析其他注解;如果没加,只会单独解析相应的注解 * * 此时只有传进来的配置类会执行 */ /** * candidateIndicators.add(Component.class.getName()); * candidateIndicators.add(ComponentScan.class.getName()); * candidateIndicators.add(Import.class.getName()); * candidateIndicators.add(ImportResource.class.getName()); */ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { // 有的话就添加到 BeanDefinitionHolder 集合中【此时传入的配置类会添加进集合中】 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 如果没有发现其他的 @Configuration 类就立即返回 if (configCandidates.isEmpty()) { return; } // 按先前确定的 @Order 值排序 configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); // Detect any custom bean name generation strategy supplied through the enclosing application context /** * 检测通过封闭的应用程序上下文提供的任何自定义 bean 名称生成策略 */ SingletonBeanRegistry sbr = null; /** * 如果 BeanDefinitionRegistry 是 SingletonBeanRegistry 的子类 * 传入的是 DefaultListableBeanFactory 是 SingletonBeanRegistry 的子类 */ if (registry instanceof SingletonBeanRegistry) { // 强转 sbr = (SingletonBeanRegistry) registry; // 没有自定义的 name if (!this.localBeanNameGeneratorSet) { // 获取 BeanName 生成器 // SingletonBeanRegistry 中是否包含 beanName 为 internalConfigurationBeanNameGenerator 的对象 BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton( AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); // 有则使用,没有则使用 Spring 默认的 if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } // environment 为空则初始化为 StandardEnvironment if (this.environment == null) { this.environment = new StandardEnvironment(); } // Parse each @Configuration class // 实例化 ConfigurationClassParser 对象,用于解析每个 @Configuration 类 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); /** * 定义两个集合 * candidates 集合用于将之前加入的 configCandidates 进行去重,因为可能有重复的配置类 * alreadyParsed 用于判断是否解析过 */ Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { /** * 解析 */ parser.parse(candidates); /** * 验证 * * 主要验证 @Configuration 的 @Bean 方法是否是静态和可覆盖的 * 静态则跳过验证 * @Configuration 类中的实例 @Bean 方法必须可以覆盖才能容纳CGLIB */ parser.validate(); // 去重 /** * 此时加了注解的普通类已经注册完成,包括 @Configuration 配置类 */ Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); // 移除所有已解析的 configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content // 读取模型并根据其内容创建 BeanDefinition if (this.reader == null) { // 实例化 ConfigurationClassBeanDefinitionReader 阅读器,用于创建 BeanDefinitions this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } // 加载 BeanDefinitions 存入集合中 this.reader.loadBeanDefinitions(configClasses); // 全部标记为已处理 alreadyParsed.addAll(configClasses); // 清空候选者集合,后面保存经过校验存在是配置类的候选者 并且 没有处理过 candidates.clear(); // 处理后工厂内的 BeanDefinition 数量大于处理前的数量 if (registry.getBeanDefinitionCount() > candidateNames.length) { // 处理后 BeanFactory 中 beanDefinitionNames 数据 String[] newCandidateNames = registry.getBeanDefinitionNames(); // 处理前 BeanFactory 中 beanDefinitionNames 数据 Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); /** * alreadyParsed + oldCandidateNames = newCandidateNames */ Set<String> alreadyParsedClasses = new HashSet<>(); // 已处理的普通类添加到 alreadyParsedClasses 集合中 for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } /** * 循环遍历处理后的 beanDefinitionNames */ for (String candidateName : newCandidateNames) { // 过滤出处理后的候选者中存在于处理前的候选者,即 alreadyParsed 中候选者 // 为什么不直接遍历 alreadyParsed 集合,而是通过这种方式? // 可能是 Spring 怕正在处理的时候,又手动添加了新的需要解析的类 if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); // 再次检查 BeanDefinition 是否是配置类的候选者 并且 没有处理过 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } // 标记所有候选者已处理完成 candidateNames = newCandidateNames; } } while (!candidates.isEmpty()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes /** * 将 ImportRegistry 注册为 bean 以支持 ImportAware 的 @Configuration类 */ if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } // 如果是 CachingMetadataReaderFactory 的子类,这里会进入判断 if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { // Clear cache in externally provided MetadataReaderFactory; this is a no-op // for a shared cache since it'll be cleared by the ApplicationContext. // 清除外部提供的 MetadataReaderFactory 缓存 // 这是一个无操作的共享缓存,因为它会通过ApplicationContext中被清除 ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } }
解析的流程委托给了 ConfigurationClassParser 这个类的parser方法来完成
public void parse(Set<BeanDefinitionHolder> configCandidates) { // 此时只有我们传入的配置类这一个元素 // 根据 BeanDefinition 的类型做不同的处理 for (BeanDefinitionHolder holder : configCandidates) { // 获取 BeanDefinition BeanDefinition bd = holder.getBeanDefinition(); try { // 是 AnnotatedBeanDefinition 的子类 if (bd instanceof AnnotatedBeanDefinition) { /** * 解析注解对象,并存入 Map<ConfigurationClass, ConfigurationClass> 集合中 * 但是这里的 BeanDefinition 是普通的 * 什么是不普通的呢?比如加了 @Bean 和各种 BeanFactoryPostProcessor 得到的 BeanDefinition 不在这里存放 * 但是在这里解析,只是不存放而已 */ parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } // 是 AbstractBeanDefinition 的子类 else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); } } // 延迟导入处理类,执行流程暂时没跟,但是到后面的代码就重复了 this.deferredImportSelectorHandler.process(); }
继续跟 parse 方法,最后执行的是 processConfigurationClass 方法,代码如下:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { // 判断是否需要跳过 if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } /** * 是否已存在 * * Map<ConfigurationClass, ConfigurationClass> configurationClasses * 是存放类之间相互引入的关系集合 */ ConfigurationClass existingClass = this.configurationClasses.get(configClass); if (existingClass != null) { // 如果当前类被别的类 @Import,则做如下处理 if (configClass.isImported()) { if (existingClass.isImported()) { existingClass.mergeImportedBy(configClass); } // Otherwise ignore new imported config class; existing non-imported class overrides it. // 否则忽略新导入的配置类; 现有的非导入类会覆盖它 return; } else { // Explicit bean definition found, probably replacing an import. // Let's remove the old one and go with the new one. // 找到显式 beanDefinition,可能替换导入,则删除旧的并使用新的 this.configurationClasses.remove(configClass); this.knownSuperclasses.values().removeIf(configClass::equals); } } // Recursively process the configuration class and its superclass hierarchy. /** * 递归处理配置类及其超类层次结构 */ SourceClass sourceClass = asSourceClass(configClass); do { sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); this.configurationClasses.put(configClass, configClass); }
这里循环处理配置类,doProcessConfigurationClass 代码如下:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 是否加了 @Component 注解,@Configuration 注解同样适用 if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // Recursively process any member (nested) classes first /** * 首先递归处理任何成员(嵌套)类 * 处理内部类 */ processMemberClasses(configClass, sourceClass); } // Process any @PropertySource annotations /** * 处理 @PropertySource 注解 */ for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } // Process any @ComponentScan annotations /** * 获取 @ComponentScan 注解数据 * * 处理 @ComponentScan 注解 * 扫描路径下加了 @Component 注解的类,并存入 BeanDefinitionMap 中 */ Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); // 判断是否需要处理 if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { // 是个集合,循环遍历 for (AnnotationAttributes componentScan : componentScans) { // The config class is annotated with @ComponentScan -> perform the scan immediately /** * 扫描 @ComponentScan 路径下符合过滤器和候选者条件的类 * 转换为 BeanDefinitionHolder,并注册到 BeanFactory 中 * * 可以理解为扫描 @ComponentScan 路径下加了 @Configuration、@Component、@Service 等的类 */ Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if needed /** * 检查扫描出来的类当中是否还有 Configuration 类 */ for (BeanDefinitionHolder holder : scannedBeanDefinitions) { // 获取原始 BeanDefinition BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } // 检查给定的 BeanDefinition 是否是配置类的候选者 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // Process any @Import annotations // SpringBoot 很多 EnableXXX 都是基于 @Import 注解来实现灵活配置的 /** * 处理 @Import 注解 * 可以引入 @Configuration 类,ImportSelector 类,ImportBeanDefinitionRegistrar 类 * * 解析 @Import 注解引入的类,ImportSelector 类、ImportBeanDefinitionRegistrar 类和 @Configuration 类作相应的处理 * ImportSelector 类需要递归处理 * ImportBeanDefinitionRegistrar 类存入 Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars 集合中 * @Configuration 类存入 Map<ConfigurationClass, ConfigurationClass> configurationClasses 集合中 * * ImportSelector 的实现类可以动态实例化一个 BeanDefinition 到 IOC 容器中 */ processImports(configClass, sourceClass, getImports(sourceClass), true); // Process any @ImportResource annotations // 处理 @ImportResource 注解 AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); if (importResource != null) { String[] resources = importResource.getStringArray("locations"); Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // Process individual @Bean methods // 处理每个 @Bean 注解方法 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces // 处理接口上的默认方法 processInterfaces(configClass, sourceClass); // Process superclass, if any // 如果有父类则处理 if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); // 排除 java.lang.Object 的父类且不存在于 knownSuperclasses 集合中 if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse // 找到超类,返回其注释元数据并递归 return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; }
这里 this.componentScanParser.parse 方法和 processImports 方法都是比较重要的方法,尤其是 processImports 方法。SpringBoot很多EnableXXX注解都是使用了Spring的ImportBeanDefinitionRegistrar 这个类来实现动态注册的,这是Spring提供的扩展点,以后会写一篇详细的博文和示例来说明,这里就先跳过,跟一下 this.componentScanParser.parse 方法:
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { /** * 此时又实例化了一个 ClassPathBeanDefinitionScanner * 并没有使用 AnnotationConfigApplicationContext 构造方法中实例化的 ClassPathBeanDefinitionScanner */ ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); // 获取 BeanName 生成器 Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator"); boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass); scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass)); // 处理代理模型 ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy"); if (scopedProxyMode != ScopedProxyMode.DEFAULT) { scanner.setScopedProxyMode(scopedProxyMode); } else { Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver"); scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass)); } scanner.setResourcePattern(componentScan.getString("resourcePattern")); /** * 遍历 @ComponentScan 中的 includeFilters * 获取符合组件扫描的条件的类型 * Filter[] includeFilters() default {}; */ for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addIncludeFilter(typeFilter); } } /** * 遍历 @ComponentScan 中的 excludeFilters * 获取不符合组件扫描的条件的类型 * Filter[] excludeFilters() default {}; */ for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addExcludeFilter(typeFilter); } } /** * 获取 @ComponentScan 中的 lazyInit * 默认不是懒加载 * 如果是懒加载,则修改 BeanDefinitionDefaults 的懒加载属性值为 True,而不是修改 BeanDefinition 的懒加载属性值为 True * 为后面应用默认值提供便利 * boolean lazyInit() default false; */ boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } // 去重存储扫描的包路径 Set<String> basePackages = new LinkedHashSet<>(); /** * 获取 @ComponentScan 中的 basePackages() * String[] basePackages() default {}; */ 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); } /** * 获取 @ComponentScan 中的 basePackageClasses * Class<?>[] basePackageClasses() default {}; */ for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) { basePackages.add(ClassUtils.getPackageName(clazz)); } // 如果没有注明扫描路径,则默认扫描 @Configuration 类所在包及其子包 if (basePackages.isEmpty()) { basePackages.add(ClassUtils.getPackageName(declaringClass)); } scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { @Override protected boolean matchClassName(String className) { return declaringClass.equals(className); } }); return scanner.doScan(StringUtils.toStringArray(basePackages)); }
话不多说,scanner.doScan 方法跟进去就完事了
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); // 循环扫描 basePackage 路径下的文件,即 @ComponentScan 注解的 value 或 basePackages 值 for (String basePackage : basePackages) { /** * 加了注解且符合条件则转换为 BeanDefinition * * AnnotatedGenericBeanDefinition 或 ScannedGenericBeanDefinition * AnnotatedGenericBeanDefinition 和 ScannedGenericBeanDefinition 都是 AbstractBeanDefinition 的子类 * 这里都转换成了 ScannedGenericBeanDefinition */ Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { // 解析 Scope 属性 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); // 使用 BeanName 生成器获取候选者的 BeanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); /** * 如果这个类是 AbstractBeanDefinition 的子类 * * 此时会进入这个判断 * * public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition * public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition * public class GenericBeanDefinition extends AbstractBeanDefinition * * 而被 @ComponentScan 注解扫描后的类都变成了 ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition * * 基本上都是 AbstractBeanDefinition 的子类 * 即先将 BeanDefinitionDefaults 的值赋给候选 BeanDefinition */ if (candidate instanceof AbstractBeanDefinition) { /** * 应用如下默认值: * setLazyInit(lazyInit); * setAutowireMode(defaults.getAutowireMode()); * setDependencyCheck(defaults.getDependencyCheck()); * setInitMethodName(defaults.getInitMethodName()); * setEnforceInitMethod(false); * setDestroyMethodName(defaults.getDestroyMethodName()); * setEnforceDestroyMethod(false); */ postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } /** * 如果这个类是 AnnotatedBeanDefinition 的子类 * * ScannedGenericBeanDefinition 或 AnnotatedGenericBeanDefinition 也是 AnnotatedBeanDefinition 的子类 * * 这个判断也会进,即跑完上一步时已经具有了默认值,但是用户可能单独为这个类配置了注解值 * 再将扫描到的注解值赋给候选 BeanDefinition */ if (candidate instanceof AnnotatedBeanDefinition) { /** * 处理自定义注解的值 * 包含的注解有 @Lazy,@Primary,@DependsOn,@Role,@Description */ AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } /** * 检查给定候选者的 beanName * * 1、是否存在于 BeanFactory 中,如果不存在则直接返回为 True * 2、校验存在的和现有的 BeanDefinition 是否兼容,兼容则返回 False * 3、抛异常 * * 此时刚进行扫描,并没有注册到 BeanFactory 中,所以一般会进 */ if (checkCandidate(beanName, candidate)) { // 转换为 BeanDefinitionHolder BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // 应用代理模式 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); /** * 由 Bean 的主要名称和别名注册 BeanDefinition * * 将 BeanDefinition 加入 Map<String, BeanDefinition>【主名】 和 Map<String, String>【别名】 集合中 */ registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
而 registerBeanDefinition 方法跟进去与我们上一篇探究的代码一样,这里就不再赘述了。
到这里 invokeBeanFactoryPostProcessors 方法就执行完成了,没执行之前 DefaultListableBeanFactory 中的 BeanDefinitionMap 中的数据如下
执行完后,我们的@Service,@Component,@Bean,@Import等注解类都已经注册到 Bean 工厂中
下一篇解析 refresh 中另一个重要的方法 finishBeanFactoryInitialization
在Spring的方法名中包含了很多 Initialization 和 Instantiation 这两个单词,一个是初始化,一个是实例化
BeanPostProcessor 的直接实现类能够干预 Bean 的初始化过程,比如 ApplicationContextAwareProcessor
BeanPostProcessor 的继承类能够干预 Bean 的实例化过程,比如 SmartInstantiationAwareBeanPostProcessor
这个先提一下,以后再详细说,希望坚持写下去。
原文链接:https://www.cnblogs.com/elewin/p/11305862.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:Java网络编程探究|乐字节
下一篇:java开发面试题目总结(更新)
- Spring系列.ApplicationContext接口 2020-06-11
- Java--注解 2020-06-11
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- 给你一份超详细 Spring Boot 知识清单 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash