本文主要接上文Spring BeanDefinition的解析过程源码分析(上)
上文讲到准备调用refresh(),本文还是不会对refresh()方法中所有方法进行分析,还是围绕BeanDefinition的解析来分析,本文篇幅可能过长!
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); ...... } } }
关键方法在于invokeBeanFactoryPostProcessors(beanFactory)的执行,先大致梳理一下 refresh()逻辑吧
prepareRefresh()准备一些刷新操作,然后obtainFreshBeanFactory()方法实际上就是获取上文Spring BeanDefinition的解析过程源码分析(上)中的下面这部分
然后调用invokeBeanFactoryPostProcessors(beanFactory)方法得到一些需要注册为Bean的class并存储在beanFactory的
对染这里还未执行invokeBeanFactoryPostProcessors(beanFactory)方法,这里在上文中Spring BeanDefinition的解析过程源码分析(上)中的this()、register(annotatedClasses)方法中就添加了这些元数据!那么下面我们开始执行invokeBeanFactoryPostProcessors(beanFactory);方法!
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //传入Bean工厂并获取容器中的Bean工厂后置处理器(注意这里Bean工厂后置处理器还没有初始化) PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); .......... }
PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); //判断我们的beanFactory是否实现了BeanDefinitionRegistry if (beanFactory instanceof BeanDefinitionRegistry) { //强行把beanFactory转为BeanDefinitionRegistry BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; //保存BeanFactoryPostProcessor类型的后置处理器 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); //保存BeanDefinitionRegistryPostProcessor类型的后置处理器 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //循环我们传递进来的beanFactoryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { //判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { //进行强制转化 BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; //调用它的后置方法 registryProcessor.postProcessBeanDefinitionRegistry(registry); //添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中 registryProcessors.add(registryProcessor); } else { //若没有实现BeanDefinitionRegistryPostProcessor接口,那么他就是BeanFactoryPostProcessor 把当前的后置处理器加入到regularPostProcessors中 regularPostProcessors.add(postProcessor); } } //定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //判断是否实现了PriorityOrdered接口的 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); } } //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //把他加入到用于保存到registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); /** * 在这里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor * 用于进行bean定义的加载 比如我们的包扫描,@import等 */ invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //调用完之后,马上clear currentRegistryProcessors.clear(); //下一步 又去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //表示没有被处理过,且实现了Ordered接口的 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); } } //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //把他加入到用于保存到registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); //调用他的后置处理方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //调用完之后,马上clear currentRegistryProcessors.clear(); //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor //定义一个重复处理的开关变量 默认值为true boolean reiterate = true; //第一次就可以进来 while (reiterate) { //进入循环马上把开关变量给改为false reiterate = false; //去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称 for (String ppName : postProcessorNames) { //没有被处理过的 if (!processedBeans.contains(ppName)) { //显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); //同时也加入到processedBeans集合中去 processedBeans.add(ppName); //再次设置为true reiterate = true; } } //对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //把他加入到用于保存到registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); //调用他的后置处理方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //进行clear currentRegistryProcessors.clear(); } //调用实现了BeanDefinitionRegistryPostProcessor的接口 他是他也同时实现了BeanFactoryPostProcessor的方法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); //调用BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else {//若当前的beanFactory没有实现了BeanDefinitionRegistry 直接调用beanFactoryPostProcessor接口的方法进行后置处理 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } //最后一步 获取容器中所有的 BeanFactoryPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); //保存BeanFactoryPostProcessor类型实现了priorityOrdered List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); //保存BeanFactoryPostProcessor类型实现了Ordered接口的 List<String> orderedPostProcessorNames = new ArrayList<>(); //保存BeanFactoryPostProcessor没有实现任何优先级接口的 List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { //processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了 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 { nonOrderedPostProcessorNames.add(ppName); } } //先调用BeanFactoryPostProcessor实现了PriorityOrdered接口的 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); //再调用BeanFactoryPostProcessor实现了Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); //调用没有实现任何方法接口的 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
别看这里这么多方法,这里重点我们看第一个invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法!
PostProcessorRegistrationDelegate
private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
执行postProcessBeanDefinitionRegistry(registry)方法
ConfigurationClassPostProcessor
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { ...... //真正的解析我们的Bean定义 processConfigBeanDefinitions(registry); }
这个方法就比较核心了,这个方法也就是找到符合Spring Bean规则的class如下!
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); //获取Spring IoC容器中目前所有Bean定义的名称 String[] candidateNames = registry.getBeanDefinitionNames(); //循环所有的Bean定义信息 for (String beanName : candidateNames) { //通过Bean的名称来获取Bean的定义对象 BeanDefinition beanDef = registry.getBeanDefinition(beanName); //判断是否有没有解析过 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } //判断是否是配置类 // checkConfigurationClassCandidate()会判断一个是否是一个配置类,并为BeanDefinition设置属性为lite或者full。 //在这儿为BeanDefinition设置lite和full属性值是为了后面在使用 // 如果加了@Configuration,那么对应的BeanDefinition为full; // 如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。 //lite和full均表示这个BeanDefinition对应的类是一个配置类 else if (ConfigurationClassUtils.checkConfiguration ClassCandidate(beanDef, this.metadataReaderFactory)) { //添加到候选的配置类集合中 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 若没有找到配置类 直接返回 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); }); //创建@CompentScan、@Import导入进来的bean名称的生成器 SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { // beanName的生成器,因为后面会扫描出所有加入到spring容器中calss类,然后把这些class // 解析成BeanDefinition类,此时需要利用BeanNameGenerator为这些BeanDefinition生成beanName BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); if (generator != null) { //设置@CompentScan导入进来的bean的名称生成器 this.componentScanBeanNameGenerator = generator; //设置@Import导入进来的bean的名称生成器 this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } //创建一个配置类解析器对象 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); //创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); //创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度 Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { //真正的解析我们的配置类 parser.parse(candidates); parser.validate(); //解析出来的配置类 Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } //真正的把我们解析出来的配置类注册到容器中 this.reader.loadBeanDefinitions(configClasses); //加入到已经解析的集合中 alreadyParsed.addAll(configClasses); candidates.clear(); //判断我们Spring IoC容器中Bean的定义数量是否 > 候选原始的bean定义的个数 if (registry.getBeanDefinitionCount() > candidateNames.length) { //获取所有的bean定义 String[] newCandidateNames = registry.getBeanDefinitionNames(); //原始的老的候选的bean定义 Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet<>(); //赋值已经解析的 for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { //表示当前循环的还没有被解析过 if (!oldCandidateNames.contains(candidateName)) { //判断有没有被解析过 BeanDefinition bd = registry.getBeanDefinition(candidateName); 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 if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } 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. ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } }
这里代码也挺多的,其核心代码在于parser.parse(candidates);和this.reader.loadBeanDefinitions(configClasses);
关于this.reader.loadBeanDefinitions(configClasses)放在文末讲
public void parse(Set<BeanDefinitionHolder> configCandidates) { for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } 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(); }
这里其实是根据BeanDefinition 的不同,传入不同的入参!核心调用的还是同一个方法processConfigurationClass()!
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { //把我们的配置类源信息和beanName包装成一个ConfigurationClass对象 processConfigurationClass(new ConfigurationClass(metadata, beanName)); }
切入processConfigurationClass()
该方法主要就是循环调用doProcessConfigurationClass(configClass, sourceClass);方法将符合Bean特征的class添加到BeanDefinitionMap中,然后将配置类添加到configurationClasses中
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } //获取我们的配置类对象 ConfigurationClass existingClass = this.configurationClasses.get(configClass); //传入的配置类是通过其他配置类的Import导入进来的 if (existingClass != null) { 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. this.configurationClasses.remove(configClass); this.knownSuperclasses.values().removeIf(configClass::equals); } } // 处理配置类,由于配置类可能存在父类(若父类的全类名是以java开头的,则除外),所有需要将configClass变成sourceClass去解析,然后返回sourceClass的父类。 // 如果此时父类为空,则不会进行while循环去解析,如果父类不为空,则会循环的去解析父类 // SourceClass的意义:简单的包装类,目的是为了以统一的方式去处理带有注解的类,不管这些类是如何加载的 SourceClass sourceClass = asSourceClass(configClass); //真正的进行配置类的解析 do { //解析我们的配置类 sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); // 将解析的配置类存储起来,这样回到parse()方法时,能取到值 this.configurationClasses.put(configClass, configClass); }
切入doProcessConfigurationClass(configClass, sourceClass);
@Nullable protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // 处理内部类,处理内部类时,最终还是调用doProcessConfigurationClass()方法 processMemberClasses(configClass, sourceClass); } //处理我们的@PropertySources注解的 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"); } } //处理@ComponentScan或者@ComponentScans注解 //从先找出类上的@ComponentScan和@ComponentScans注解的所有属性(例如basePackages等属性值) Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { //循环解析(我们解析出来的AnnotationAttributes) for (AnnotationAttributes componentScan : componentScans) { //解析@ComponentScan和@ComponentScans配置的扫描的包所包含的类 // 比如 basePackages = com.tiantang.study, 那么在这一步会扫描出这个包及子包下的class,然后将其解析成BeanDefinition // (BeanDefinition可以理解为等价于BeanDefinitionHolder) //把我们扫描出来的类变为bean定义的集合 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // 通过上一步扫描包com.tiantang.com下的类,有可能扫描出来的bean中可能也添加了ComponentScan或者ComponentScans注解. //所以这里需要循环遍历一次,进行递归(parse),继续解析,直到解析出的类上没有ComponentScan和ComponentScans // (这时3.1这一步解析出componentScans为空列表,不会进入到if语句,递归终止) for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } //判断当前扫描出来的bean定义是不是一个配置类,若是的话 直接进行递归解析 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { //递归解析 parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } //处理Import注解注册的bean,这一步只会将import注册的bean变为ConfigurationClass,不会变成BeanDefinition // 而是在loadBeanDefinitions()方法中变成BeanDefinition,再放入到BeanDefinitionMap中 // 关于Import注解,后面会单独写文章介绍 processImports(configClass, sourceClass, getImports(sourceClass), true); //处理@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); } } //处理@Bean methods获取到我们配置类中所有标注了@Bean的方法 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } //处理配置类接口的 processInterfaces(configClass, sourceClass); //处理配置类的父类的 if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); 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(); } } //没有父类解析完成 return null; }
其中有个很重要的方法this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());和ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)
先讲checkConfigurationClassCandidate,因为this.componentScanParser.parse方法调用栈比较长!
切入checkConfigurationClassCandidate
该方法是用来判断一个是否是一个配置类,并为BeanDefinition设置属性为lite或者full。如果加了@Configuration,那么对应的BeanDefinition为full,如果加了@Bean,@Component,@ComponentScan,@Import,@ImportResource这些注解,则为lite。lite和full均表示这个BeanDefinition对应的类是一个配置类。 public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) { // ... 省略部分不重要的代码 if (isFullConfigurationCandidate(metadata)) { // 含有@Configuration注解,那么对应的BeanDefinition的configurationClass属性值设置为full beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } else if (isLiteConfigurationCandidate(metadata)) { // 含有@Bean,@Component,@ComponentScan,@Import,@ImportResource注解 // configurationClass属性值设置为lite beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else { return false; } return true; }
切入this.componentScanParser.parse()
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { //给扫描器设置beanName的生成器对象 ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator"); boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass); scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass)); //设置bean的域代理模型 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包含的属性 for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addIncludeFilter(typeFilter); } } //设置ComponentScan对象的excludeFilters不包含的属性 for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) { for (TypeFilter typeFilter : typeFiltersFor(filter)) { scanner.addExcludeFilter(typeFilter); } } //是否懒加载 boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } //包路径 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); } for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) { basePackages.add(ClassUtils.getPackageName(clazz)); } 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(StringUtils.toStringArray(basePackages))
doScan方法主要是实现了扫描的逻辑,也就是通过findCandidateComponents(basePackage)方法扫描指定包下的符合Bean特征的class,然后存放到candidates ,然后通过一系列判断进入registerBeanDefinition方法,将符合Bean特征的Bean注册到beanDefinitionMap中去
//类路径Bean定义扫描器扫描给定包及其子包 protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); //创建bean定义的holder对象用于保存扫描后生成的bean定义对象 Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); //循环我们的包路径集合 for (String basePackage : basePackages) { //调用父类ClassPathScanningCandidateComponentProvider的方法 //扫描给定类路径,获取符合条件的Bean定义 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); //遍历扫描到的Bean for (BeanDefinition candidate : candidates) { //获取@Scope注解的值,即获取Bean的作用域 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); //为Bean设置作用域 candidate.setScope(scopeMetadata.getScopeName()); 为Bean生成名称。也就是设置我们的beanName String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); /如果扫描到的Bean不是Spring的注解Bean,则为Bean设置默认值, //设置Bean的自动依赖注入装配属性等 if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } //处理jsr250相关的组件 if (candidate instanceof AnnotatedBeanDefinition) { //处理注解Bean中通用的注解,在分析注解Bean定义类读取器时已经分析过 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //把我们解析出来的组件bean定义注册到Spring IoC容器中 if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); //根据注解中配置的作用域,为Bean应用相应的代理模式 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); //注册到Spring IoC容器中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
其中findCandidateComponents(basePackage)和registerBeanDefinition(definitionHolder, this.registry)方法尤为重要!
public Set<BeanDefinition> findCandidateComponents(String basePackage) { if (this.componentsIndex != null && indexSupportsIncludeFilters()) { return addCandidateComponentsFromIndex(this.componentsIndex, basePackage); } else { return scanCandidateComponents(basePackage); } }
执行scanCandidateComponents方法
该方法的核心逻辑就是在指定的包路径下,及其子包扫描符合规则的类,并收集为candidates返回
private Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); try { //补全扫描路径,扫描所有.class文件 classpath*:com/mydemo/**/*.class String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; //定位资源 Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = logger.isTraceEnabled(); boolean debugEnabled = logger.isDebugEnabled(); for (Resource resource : resources) { if (traceEnabled) { logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { //通过ASM获取class元数据,并封装在MetadataReader元数据读取器中 MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); //判断该类是否符合@CompoentScan的过滤规则 //过滤匹配排除excludeFilters排除过滤器(可以没有),包含includeFilter中的包含过滤器(至少包含一个)。 if (isCandidateComponent(metadataReader)) { //把元数据转化为 BeanDefinition ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); //判断是否是合格的bean定义 if (isCandidateComponent(sbd)) { if (debugEnabled) { logger.debug("Identified candidate component class: " + resource); } //加入到集合中 candidates.add(sbd); } else { //不合格 不是顶级类、具体类 if (debugEnabled) { logger.debug("Ignored because not a concrete top-level class: " + resource); } } } else { //不符@CompoentScan过滤规则 if (traceEnabled) { logger.trace("Ignored because not matching any filter: " + resource); } } } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to read candidate component class: " + resource, ex); } } else { if (traceEnabled) { logger.trace("Ignored because not readable: " + resource); } } } } catch (IOException ex) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex); } return candidates; }
这里有个判断是否符合过滤规则的方法isCandidateComponent()
切入isCandidateComponent()
判断元信息读取器读取的类是否符合容器定义的注解过滤规则
//@CompoentScan的过滤规则支持5种 (注解、类、正则、aop、自定义) protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { //如果读取的类的注解在排除注解过滤规则中,返回false for (TypeFilter tf : this.excludeFilters) { if (tf.match(metadataReader, getMetadataReaderFactory())) { return false; } } //如果读取的类的注解在包含的注解的过滤规则中,则返回ture for (TypeFilter tf : this.includeFilters) { //判断当前类的注解是否match规则 if (tf.match(metadataReader, getMetadataReaderFactory())) { //是否有@Conditional注解,进行相关处理 return isConditionMatch(metadataReader); } } return false; }
来都来了,看看match方法如何实现的吧!
tf.match()
@Override public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { //检查当前类的注解是否符合规律规则 if (matchSelf(metadataReader)) { return true; } //check 类名是否符合规则 ClassMetadata metadata = metadataReader.getClassMetadata(); if (matchClassName(metadata.getClassName())) { return true; } //如果有继承父类 if (this.considerInherited) { String superClassName = metadata.getSuperClassName(); if (superClassName != null) { // Optimization to avoid creating ClassReader for super class. Boolean superClassMatch = matchSuperClass(superClassName); if (superClassMatch != null) { if (superClassMatch.booleanValue()) { return true; } } else { // Need to read super class to determine a match... try { if (match(metadata.getSuperClassName(), metadataReaderFactory)) { return true; } } catch (IOException ex) { logger.debug("Could not read super class [" + metadata.getSuperClassName() + "] of type-filtered class [" + metadata.getClassName() + "]"); } } } } //如果有实现接口 if (this.considerInterfaces) { for (String ifc : metadata.getInterfaceNames()) { // Optimization to avoid creating ClassReader for super class Boolean interfaceMatch = matchInterface(ifc); if (interfaceMatch != null) { if (interfaceMatch.booleanValue()) { return true; } } else { // Need to read interface to determine a match... try { if (match(ifc, metadataReaderFactory)) { return true; } } catch (IOException ex) { logger.debug("Could not read interface [" + ifc + "] for type-filtered class [" + metadata.getClassName() + "]"); } } } } return false; }
我们接着matchSelf方法深入
protected boolean matchSelf(MetadataReader metadataReader) { //获取注解元数据 AnnotationMetadata metadata = metadataReader.getAnnotationMetadata(); //check 注解及其派生注解中是否包含@Component //获取当前类的注解 metadata.hasAnnotation @Controller //获取当前类的注解及其派生注解 metadata.hasAnnotation @Controller包含的@Component\@Documented等等 return metadata.hasAnnotation(this.annotationType.getName()) || (this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName())); }
这段代码可以解决Spring发现@Configuration、@Controller、@Service这些注解修饰的类的,在这些注解底层都是使用@Component的派生注解,而spring通过metadata.hasMetaAnnotation()方法获取到这些注解包含@Component,所以都可以扫描到
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) { BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry); }
public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } }
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { ...... } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
那么这里this.beanDefinitionMap.put(beanName, beanDefinition);就是添加beanDefinitionMap中的核心方法
该方法实际上是将通过@Import、@Bean等注解方式注册的类解析成BeanDefinition,然后注册到BeanDefinitionMap中。
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); // 循环调用loadBeanDefinitionsForConfigurationClass() for (ConfigurationClass configClass : configurationModel) { loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }
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; } // 如果一个bean是通过@Import(ImportSelector)的方式添加到容器中的,那么此时configClass.isImported()返回的是true // 而且configClass的importedBy属性里面存储的是ConfigurationClass就是将bean导入的类 //是不是通过@Import导入进来的 if (configClass.isImported()) { registerBeanDefinitionForImportedConfigurationClass(configClass); } // 判断当前的bean中是否含有@Bean注解的方法,如果有,需要把这些方法产生的bean放入到BeanDefinitionMap当中 for (BeanMethod beanMethod : configClass.getBeanMethods()) { loadBeanDefinitionsForBeanMethod(beanMethod); } //是不是通过@ImportResources导入进来的 loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); // 如果bean上存在@Import注解,且import的是一个实现了ImportBeanDefinitionRegistrar接口,则执行ImportBeanDefinitionRegistrar的registerBeanDefinitions()方法,也就是判断是不是通过ImportBeanDefinition注解导入进来的 loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
registerBeanDefinitionForImportedConfigurationClass(configClass);
通过@Import导入进来的执行registerBeanDefinitionForImportedConfigurationClass(configClass)方法:
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { //获取我们的配置类的源信息 AnnotationMetadata metadata = configClass.getMetadata(); //构建为我们的bean定义 AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata); //设置他的scope ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName()); //获取bean的名称 String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry); //处理我们的JRS250组件的 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 + "'"); } }
loadBeanDefinitionsForBeanMethod(beanMethod);
通过@Bean导入进来的执行loadBeanDefinitionsForBeanMethod(beanMethod)方法:
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); ....... this.registry.registerBeanDefinition(beanName, beanDefToRegister); }
这里又将符合Bean特征的class添加到BeanDefinitionMap中
,那么至此整个invokeBeanFactoryPostProcessors(beanFactory);方法就至此完了!这里把符合Bean特征的class解析成BeanDefinition存储在beanFactory中
然后后期通过finishBeanFactoryInitialization(beanFactory)方法实例化这些Bean的操作!