美文网首页springspring
spring源码分析1

spring源码分析1

作者: 念䋛 | 来源:发表于2021-08-17 21:12 被阅读0次

    接着上一篇文章将 refresh方法
    首先看一下测试项目代码
    主类,将Myconfiguration.class注入进ApplictionContext


    image.png

    配置类


    image.png
    Car类实现了BeanDefinitionRegistryPostProcessor接口
    image.png
    MySpringBean标注了@Component
    image.png

    看一下refresh方法,(AbstractApplicationContext#refresh)

    @Override
    public void refresh() throws BeansException, IllegalStateException {
       synchronized (this.startupShutdownMonitor) {
          StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
          // Prepare this context for refreshing.
          prepareRefresh();
          // Tell the subclass to refresh the internal bean factory.
    // AnnotationConfigApplicationContext因为继承   GenericApplicationContext
    //点进obtainFreshBeanFactory()方法,发现beanFactory是DefaultListableBeanFactory();
          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.
             postProcessBeanFactory(beanFactory);
             StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
             // Invoke factory processors registered as beans in the context.
             invokeBeanFactoryPostProcessors(beanFactory);
             // Register bean processors that intercept bean creation.
             registerBeanPostProcessors(beanFactory);
             beanPostProcess.end();
             // Initialize message source for this context.
             initMessageSource();
             // Initialize event multicaster for this context.
             initApplicationEventMulticaster();
             // Initialize other special beans in specific context subclasses.
             onRefresh();
             // Check for listener beans and register them.
             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.
             destroyBeans();
             // Reset 'active' flag.
             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();
             contextRefresh.end();
          }
       }
    }
    

    这里就是spring里关于bean的核心方法,笔者并没有全部看过,这里也介绍bean的主线代码,继续分析
    AbstractApplicationContext#invokeBeanFactoryPostProcessors方法,
    这里就涉及到最重要的类ConfigurationClassPostProcess,首先看一下继承关系,实现了
    BeanDefinitionRegistryPostProcessor(postProcessBeanDefinitionRegistry)和
    BeanFactoryPostProcessor(postProcessBeanFactory),后续对调用这两个方法


    image.png
    image.png

    PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中
    主要作用就是通过实现BeanDefinitionRegistryPostProcessor 接口类(一般指的是ConfigurationClassPostProcessor类)的postProcessBeanDefinitionRegistry方法扫面项目,将需要的类(比如@service @controller @configuration注解标注的类)加入到beanDefinitionMap中,并调用实现BeanFactoryPostProcessor的类的
    postProcessBeanFactory方法修改beanDefinition,
    在invokeBeanFactoryPostProcessors有getBean方法,会将bean放到一级缓存中,但是没有赋值属性


    image.png
    public static void invokeBeanFactoryPostProcessors(
          ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
       // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    //已经处理过的bean,防止bean后置处理器被重复的执行
       Set<String> processedBeans = new HashSet<>();
    //判断beanFacroty是否实现BeanDefinitionRegistry,因为需要获取bean和注册bean的功能
       if (beanFactory instanceof BeanDefinitionRegistry) {
          BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    // BeanFactoryPostProcessor实现类的集合,过滤的是入参beanFactoryPostProcessors中的
    // BeanFactoryPostProcessor接口的实现类
          List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    // BeanDefinitionRegistryPostProcessor实现类的集合
          List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    // beanFactoryPostProcessors通过AbstractApplicationContext#addBeanFactoryPostProcessor方法添加的,
    //springboot在启动的时候会调用addBeanFactoryPostProcessor方法
          for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    //如果手动添加的BeanDefinitionRegistry是BeanDefinitionRegistryPostProcessor的实现类
             if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                      (BeanDefinitionRegistryPostProcessor) postProcessor;
    //调用postProcessBeanDefinitionRegistry方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
    //添加到registryProcessors中
                registryProcessors.add(registryProcessor);
             }
             else {
    //如果不是BeanDefinitionRegistryPostProcessor的实现类,就是BeanFactoryPostProcessor的实现类,添加到regularPostProcessors
                regularPostProcessors.add(postProcessor);
             }
          }
    
          // Do not initialize FactoryBeans here: We need to leave all regular beans
          // uninitialized to let the bean factory post-processors apply to them!
          // Separate between BeanDefinitionRegistryPostProcessors that implement
          // PriorityOrdered, Ordered, and the rest.
          List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
          // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    //从DefaultListableBeanFactory的beanDefinitionNames成员变量中获取//BeanDefinitionRegistryPostProcessor的bean的处理器名称
          String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
          for (String ppName : postProcessorNames) {
    //过滤,只留实现PriorityOrdered接口的类,排序用
             if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    //getBean获取bean,添加到currentRegistryProcessors中,这是马上就要处理的集合,
    // getBean获取的类是ConfigurationClassPostProcessor
    //getBean的源码后续会分析到
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    //添加到processedBeans中,这是代表已经处理的集合
                processedBeans.add(ppName);
             }
          }
          sortPostProcessors(currentRegistryProcessors, beanFactory);
    // 添加registryProcessors集合
          registryProcessors.addAll(currentRegistryProcessors);
    //执行postProcessBeanDefinitionRegistry方法,这里出现的一般都是
    //ConfigurationClassPostProcessor ,这个类是springioc容器最重要的类
          invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
    //清空currentRegistryProcessors,后续还会用到
          currentRegistryProcessors.clear();
    
          // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    //从DefaultListableBeanFactory的beanDefinitionNames成员变量中获取
    //BeanDefinitionRegistryPostProcessor的bean的处理器名称,代码和上面一样,执行实现
    //Ordered接口的类,排序用
          postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
          for (String ppName : postProcessorNames) {
    
    //唯一不同的是,这里多了一个判断条件,过滤掉已经指定过的bean
             if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
             }
          }
          sortPostProcessors(currentRegistryProcessors, beanFactory);
          registryProcessors.addAll(currentRegistryProcessors);
          invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
          currentRegistryProcessors.clear();
    
          // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    //执行剩下的bean,因为项目中创建了Car类并且实现BeanDefinitionRegistryPostProcessor
    //接口,所以这里剩下的只有car
          boolean reiterate = true;
          while (reiterate) {
             reiterate = false;
             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
             for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
    // currentRegistryProcessors马上就要处理的集合
                   currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    //已经处理的bean,避免重复执行
                   processedBeans.add(ppName);
                   reiterate = true;
                }
             }
             sortPostProcessors(currentRegistryProcessors, beanFactory);
             registryProcessors.addAll(currentRegistryProcessors);
             invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
             currentRegistryProcessors.clear();
          }
    
          // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    //调用registryProcessors和regularPostProcessors的postProcessBeanFactory方法
    
          invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
          invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
       }
    
       else {
          // Invoke factory processors registered with the context instance.
    //如果bean工厂没有实现BeanDefinitionRegistry    接口,说明没有注册Bean定义的能力
    // 那么就直接调用BeanDefinitionRegistryPostProcessor#postProcessBeanFactory方法
          invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
       }
    
       // Do not initialize FactoryBeans here: We need to leave all regular beans
       // uninitialized to let the bean factory post-processors apply to them!
    //获取BeanFactoryPostProcessor接口的实例名称
       String[] postProcessorNames =
             beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
       // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
       // Ordered, and the rest.
    //实现PriorityOrdered和BeanFactoryPostProcessors接口的类
       List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    //实现Ordered和BeanFactoryPostProcessors接口类名称(beanDefinitionMap的key)
       List<String> orderedPostProcessorNames = new ArrayList<>();
    //没有实现PriorityOrdered和Ordered接口的类名称(beanDefinitionMap的key)
       List<String> nonOrderedPostProcessorNames = new ArrayList<>();
       for (String ppName : postProcessorNames) {
    //已经处理过的bean,什么也不做
          if (processedBeans.contains(ppName)) {
             // skip - already processed in first phase above
          }
    //实现PriorityOrdered接口的类getBean并add进priorityOrderedPostProcessors
          else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
             priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
          }
    //实现Ordered接口类名称add orderedPostProcessorNames
          else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
             orderedPostProcessorNames.add(ppName);
          }
    //剩余类名称的add进nonOrderedPostProcessorNames
          else {
             nonOrderedPostProcessorNames.add(ppName);
          }
       }
    //下面的代码就是执行BeanFactoryPostProcessor的postProcessBeanFactory方法
       // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
       sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
       invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
       // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
       List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
       for (String postProcessorName : orderedPostProcessorNames) {
          orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
       }
       sortPostProcessors(orderedPostProcessors, beanFactory);
       invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
       // Finally, invoke all other BeanFactoryPostProcessors.
       List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
       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();
    }
    
    

    下面两张图体现了当调用
    ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法之后将car注入到beanDefinitionMap中


    image.png
    image.png

    invokeBeanDefinitionRegistryPostProcessors方法调用类的
    postProcessBeanDefinitionRegistry方法,其实就是调用
    ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法,为什么是这个类,已经分析过了,当调用postProcessBeanDefinitionRegistry方法的时候,最终调用的是processConfigBeanDefinitions方法,上两张图注意到car的注入,那car是如何通过processConfigBeanDefinitions方法,注入进ioc容器中的

    
    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
       List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    //从现有的beanDefinitionNames中获取bean的名称①
       String[] candidateNames = registry.getBeanDefinitionNames();
    
       for (String beanName : candidateNames) {
    //获取beanDefinition
          BeanDefinition beanDef = registry.getBeanDefinition(beanName);
    //判断类是否被解析过,解析过的类返回不为null,这里涉及到类是完成配置类还是非完全配置类
          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注解,如果没有看是否标注了@Component@ComponentScan
    //@Import@ImportResource,如果还没有则看是否包含@Bean注解的方法,以上都没有则返回false ② 
          else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
    //执行完下面的方法时configCandidates只有MyConfiguration配置类,
    //有MyConfiguration,不是因为标注了@configuration注解是在new AnnotationConfigApplicationContext(Myconfiguration.class)时候,存入进beanDefinitionMaps中的
    //这里有个疑问为什么
    //没有MySpringBean呢,到现在为止还没有涉及到注解,在解析MyConfiguration配置类的代码的时候
    //通过MyConfiguration类的@ComponentScan注解就会
    //把MySpringBean扫描出来并放到beanDefinitionMap中, 
    //MyConfiguration标注了@Configuration,不但满足了上面的
    //checkConfigurationClassCandidate条件,而且还是FULL类型的配置类
             configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
          }
       }
    
       // Return immediately if no @Configuration classes were found
       if (configCandidates.isEmpty()) {
          return;
       }
    
       // Sort by previously determined @Order value, if applicable
    //根据类的@Order排序,这就是我们经常使用的,用@Order来决定类解析的顺序,
    //@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
       SingletonBeanRegistry sbr = null;
       if (registry instanceof SingletonBeanRegistry) {
          sbr = (SingletonBeanRegistry) registry;
          if (!this.localBeanNameGeneratorSet) {
             BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
                   AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
             if (generator != null) {
                this.componentScanBeanNameGenerator = generator;
                this.importBeanNameGenerator = generator;
             }
          }
       }
    
       if (this.environment == null) {
          this.environment = new StandardEnvironment();
       }
    
       // Parse each @Configuration class
    //创建解析器
       ConfigurationClassParser parser = new ConfigurationClassParser(
             this.metadataReaderFactory, this.problemReporter, this.environment,
             this.resourceLoader, this.componentScanBeanNameGenerator, registry);
    //此时configCandidates只有MyConfiguration一个类
       Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
       Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
       do {
          StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
    //解析配置类,当执行这个方法的时候,就会解析出很多类,其中就包括MySpringBean类③
          parser.parse(candidates);
          parser.validate();
    //获取扫描到的类,此时还没有放到beanDefinitionMap中
          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());
          }
    //将解析出来的配置类存放到beanDefinitionMap中,④
          this.reader.loadBeanDefinitions(configClasses);
    //将加载的类放到alreadyParsed中
          alreadyParsed.addAll(configClasses);
          processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
    
          candidates.clear();
    //因为有扫描的类存放到beanDefinitionMap中,并且类中可能还有@Bean @Import等注解,所以下面一定大于
          if (registry.getBeanDefinitionCount() > candidateNames.length) {
             String[] newCandidateNames = registry.getBeanDefinitionNames();
    // candidateNames 为方法最开始定义的,里面只有spring启动的时候存放的配置类         
    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();
       }
    }
    
    

    ①解释为什么configCandidates只有MyConfiguration配置类


    image.png

    ②ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)
    我们只关注checkConfigurationClassCandidate方法中的部分代码

    Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
    //判断是否标注了@Configuration并且proxyBeanMethods属性是否为false再取反即使判断是否为true,默认为true
    if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
    //定义该类为完全配置类,对于什么是完全配置类后续会分析
       beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
    }
    //判断否标注了@Component@ComponentScan@Import@ImportResource,如果还没有则看是否包含@Bean注解的方法, 
    else if (config != null || isConfigurationCandidate(metadata)) {
       beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    }
    //以上都没有则返回false
    else {
       return false;
    }
    
    

    ③ 解析到的配置类

    image.png
    Parse方法调用结束后,共扫描出3个类
    image.png
    查看parser.parse(candidates)
    ConfigurationClassParser#parse(Set<BeanDefinitionHolder> configCandidates)
    -->ConfigurationClassParser#processConfigurationClass
    -->ConfigurationClassParser#doProcessConfigurationClass
    在doProcessConfigurationClass方法中可以大概的看出
    主要是看类是否包含@Component @PropertySources @ComponentScans @ImportResource注释 如果ComponentScans注解,通过路径还要扫描类,
    提一下在spring解析的时候,如果@ComponentScans的basePackages为空的时候,扫描路径就是当前类所在的包,这段代码在ComponentScanAnnotationParser的parse方法中
    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));
    }
    //如果为null,使用当前类所在的包
    if (basePackages.isEmpty()) {
       basePackages.add(ClassUtils.getPackageName(declaringClass));
    }
    
    

    下一步呢 就是把包下所有的类都找到,并根据excludeFilters includeFilters的规则,找到标注了@Component注解的类,这里就不分析了,关注一下
    ClassPathBeanDefinitionScanner#doScan方法下的
    Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
    basePackage就是包的扫描路径, findCandidateComponents方法中查找包下的所有类,在遍历,过滤出标注了@Component注解的类

    image.png
    this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); 方法的第一行代码就new ClassPathBeanDefinitionScanner,并没有使用AnnotationConfigApplicationContext构造方法new ClassPathBeanDefinitionScanner对象,方法里面解析了@ConfigurationScan注解的属性,根据属性扫描类,最后scanner.doScan(StringUtils.toStringArray(basePackages));来扫描,并判断beanName 不能重复,如果重复则抛出异常
    还要介绍一下
    ConfigurationClassParser# doProcessConfigurationClass的下面这段代码
    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
    主要是通过@Import(ImportSelector实现类.class) 的selectImports导入的类
    包装成configClass,并赋值importBy为标注了@import的元类
    https://www.jianshu.com/p/4223ea69eb1f 这篇文章分析过是符合导入的
    到此为止,把所有@ConfigurationScan扫描的类和@import的类都放到configClasses中
    是通过ConfigurationClassParser#processConfigurationClass
    this.configurationClasses.put(configClass, configClass);
    这个方法存放进configClasses的
    image.png
    • ④this.reader.loadBeanDefinitions(configClasses); 将扫描的类加载进beanDefinitionMap中,并在加载之前,扫面类中是否含有@Bean注解,如果有也将扫面进beanDefinitionMap中
    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;
       }
    //如果当前的类是通过@Import导入的,是在
    // ConfigurationClassParser#doProcessConfigurationClass的
    //processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
    //将标注@Import获取出来的,这段代码就是将@Import标注的类存放beanDefinitionMap中
       if (configClass.isImported()) {
          registerBeanDefinitionForImportedConfigurationClass(configClass);
       }
    //如果configClass中有@bean方法,也将返回类存放进beanDefinitionMap中,key为方法名称
       for (BeanMethod beanMethod : configClass.getBeanMethods()) {
          loadBeanDefinitionsForBeanMethod(beanMethod);
       }
    //是不是通过@ImportResources注解导入进来的
    loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
    //是否实现ImportBeanDefinitionRegistrar,  ImportBeanDefinitionRegistrar是扩展接口//通过registerBeanDefinitions手动的注册beanDefinition, 实现//ImportBeanDefinitionRegistrar的类都是通过@Import导入的,并且实现类本身不会注入进//beanDefinitionMap中
    loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
    }
    
    

    以上是关于ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法
    下面介绍ConfigruationClassPostProcessor#postProcessBeanFactory方法
    那我们在回到最开始说的
    AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中的
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);调用的就
    ConfigruationClassPostProcessor#postProcessBeanFactory方法

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
       int factoryId = System.identityHashCode(beanFactory);
       if (this.factoriesPostProcessed.contains(factoryId)) {
          throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + beanFactory);
       }
       this.factoriesPostProcessed.add(factoryId);
       if (!this.registriesPostProcessed.contains(factoryId)) {
          // BeanDefinitionRegistryPostProcessor hook apparently not supported...
          // Simply call processConfigurationClasses lazily at this point then.
          processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
       }
    
       enhanceConfigurationClasses(beanFactory);
       beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
    }
    

    enhanceConfigurationClasses方法对Bean的增强
    遍历所有的beanDefinitionMap中的beanDefinition
    如果类ConfigurationClassUtils.CONFIGURATION_CLASS_FULL前面提到过,就是类被@Configuration注释了,就会被CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类,
    代理类的用处是什么呢,下面两张图可以解释,本次分析的
    AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);代码不会创建Bean,下面两张图不是执行invokeBeanFactoryPostProcessors代码时打印的


    image.png
    image.png

    还没有介绍@Conditional的注解的使用,
    this.reader.loadBeanDefinitions(configClasses)执行这个方法的时候,会解析@Conditional的一系列注解,springboot 中使用的是SpringBootCondition#matches方法,
    ConditionOutcome outcome = getMatchOutcome(context, metadata);
    getMatchOutcome方法是抽象方法具体的实现,如下就是OnBeanCondition的getMatchOutcome方法

    @Conditional(OnBeanCondition.class)
    public @interface ConditionalOnBean
    

    总结一下
    本文其实主要介绍的就是

    AbstractApplicationContext#refresh方法的invokeBeanFactoryPostProcessors(beanFactory);方法
    invokeBeanFactoryPostProcessors方法主要就是调用ConfigruationClassPostProcessor的postProcessBeanDefinitionRegistry方法和postProcessBeanFactory方法
    postProcessBeanDefinitionRegistry方法的作用是首先通过@ComponentScans扫描标注了@Component的类添加到beanDefinitionMap,遍历beanDefinitionMap如果标注@Import注解,根据selectImports返回的数组添加到configClasses中,再遍历configClasses,把标注@Bean @ImportSource 包装成beanDefintion添加到beanDefinitionMap中.
    postProcessBeanFactory方法标注了@Configuration类,定义为增强类CGLIB代理,将beanDefinition中的beanClass属性替换成被代理之后的类.

    相关文章

      网友评论

        本文标题:spring源码分析1

        本文链接:https://www.haomeiwen.com/subject/tmoibltx.html