Spring源码分析(五)

refresh方法分析中

invokeBeanFactoryPostProcessors继续分析

上篇分析了invokeBeanFactoryPostProcessors主要方法的作用,这篇我们对postProcessBeanDefinitionRegistry和postProcessBeanFactory继续深入分析下,postProcessBeanFactory。

postProcessBeanDefinitionRegistry深入分析

老样子先上类图
在这里插入图片描述

	/**
	 * Derive further bean definitions from the configuration classes in the registry.
	 */
	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
		// 防止被重复调用
		int registryId = System.identityHashCode(registry);
		if (this.registriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
		}
		if (this.factoriesPostProcessed.contains(registryId)) {
			throw new IllegalStateException(
					"postProcessBeanFactory already called on this post-processor against " + registry);
		}
		this.registriesPostProcessed.add(registryId);

		// 真正要执行的方法
		processConfigBeanDefinitions(registry);
	}

processConfigBeanDefinitions分析

/**
 * Build and validate a configuration model based on the registry of
 * {@link Configuration} classes.
 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
    //  获取BeanFactory中的beanDefinitionNames,这里面有六个,其中一个是我们自己register进去的,其他五个哪里来的呢
    // 如果之前看过我的源码分析,就会知道初始化AnnotationConfigApplicationContext这个类的时候回我们注册几个默认的,详细可以去看registerAnnotationConfigProcessors这个方法
    String[] candidateNames = registry.getBeanDefinitionNames();

    for (String beanName : candidateNames) {
        // 获取BeanDefinition
        BeanDefinition beanDef = registry.getBeanDefinition(beanName);
        // 如果bean被解析过,if 属性成立,这里是为了防止重复解析
        if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
            if (logger.isDebugEnabled()) {
                logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
            }
        }
        // ConfigurationClassUtils.checkConfigurationClassCandidate 解析了当前bean是否是配置类,关于其详细内容,后面解析
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            // 添加到配置类集合中
            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 注解的话)
    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(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
    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    // 用来保存尚未解析的配置类
    Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
    // 用来保存已经解析的配置类
    Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        // 开始解析。后面详细分析
        parser.parse(candidates);
        // 这里的校验是校验如果是被 @Configuration修饰且proxyBeanMethods属性为true,则类不能为final。如果@Bean修饰的方法,则必须是可覆盖的.
        // 因为@Configuration(proxyBeanMethods = true) 是需要cglib代理的,所以不能为终态, @Bean也一样
        // 是否需要代码是根据 类或方法上的 @Scope注解指定的,默认都是不代理
        parser.validate();

        // configClasses  保存这次解析出的配置类
        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());
        }
        // 注册bean
        this.reader.loadBeanDefinitions(configClasses);
        alreadyParsed.addAll(configClasses);

        candidates.clear();
        // 说明有bean注册了,则需要解析新的bean
        if (registry.getBeanDefinitionCount() > candidateNames.length) {
            String[] newCandidateNames = registry.getBeanDefinitionNames();
            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)) {
                    // 过滤出未解析的bean检测是否是未解析过的配置类
                    BeanDefinition bd = registry.getBeanDefinition(candidateName);
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                            !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                        // 如果是未解析的配置类,则保存到candidates中
                        candidates.add(new BeanDefinitionHolder(bd, candidateName));
                    }
                }
            }
            candidateNames = newCandidateNames;
        }
    }
    // 如果 candidates 不为空,则说明有未被解析的配置类,循环解析。

    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)) {
        // 到这里已经把配置类解析完毕了。
        // 将ImportRegistry  注册为 bean,以支持ImportAware @Configuration 类
        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();
    }
}

简单来说就是把我们的配置类全部转换为BeanDefinition,什么是配置类呢,怎么判定呢?我们继续分析
ConfigurationClassUtils.checkConfigurationClassCandidate

checkConfigurationClassCandidate分析

/**
 * Check whether the given bean definition is a candidate for a configuration class
 * (or a nested component class declared within a configuration/component class,
 * to be auto-registered as well), and mark it accordingly.
 * @param beanDef the bean definition to check
 * @param metadataReaderFactory the current factory in use by the caller
 * @return whether the candidate qualifies as (any kind of) configuration class
 */
public static boolean checkConfigurationClassCandidate(
        BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {

    // 获取className
    String className = beanDef.getBeanClassName();
    if (className == null || beanDef.getFactoryMethodName() != null) {
        return false;
    }

    // 之前我们通过context.register(SpringApplication.class方法,所以肯定会进入第一个分支,其他情况后面分析。
    AnnotationMetadata metadata;
    if (beanDef instanceof AnnotatedBeanDefinition &&
            className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
        // Can reuse the pre-parsed metadata from the given BeanDefinition...
        metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
    }
    else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
        // Check already loaded Class if present...
        // since we possibly can't even load the class file for this Class.
        Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
        if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
                BeanPostProcessor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
                EventListenerFactory.class.isAssignableFrom(beanClass)) {
            return false;
        }
        metadata = AnnotationMetadata.introspect(beanClass);
    }
    else {
        try {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
            metadata = metadataReader.getAnnotationMetadata();
        }
        catch (IOException ex) {
            if (logger.isDebugEnabled()) {
                logger.debug("Could not find class file for introspecting configuration annotations: " +
                        className, ex);
            }
            return false;
        }
    }

    // 获取bean上的Configuration 注解的属性。如果没有被 @Configuration 修饰 config 则为null
    Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
    if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
        // 如果被 @Configuration 修饰 &&  proxyBeanMethods 属性为 true。 @Configuration 的 proxyBeanMethods  属性默认值即为 true。
        beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
    }
    // 如果被 @Configuration 修饰 &&  isConfigurationCandidate(metadata) = true
    else if (config != null || isConfigurationCandidate(metadata)) {
        // 设置 CONFIGURATION_CLASS_ATTRIBUTE 为 lite
        beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    }
    else {
        return false;
    }

    // It's a full or lite configuration candidate... Let's determine the order value, if any.
    Integer order = getOrder(metadata);
    if (order != null) {
        beanDef.setAttribute(ORDER_ATTRIBUTE, order);
    }

    return true;
}

直接进入finishBeanFactoryInitialization说明

在这里插入图片描述
鉴于invokeBeanFactoryPostProcessors体系太庞大,后面还有单独继续分析其中没有分析到的方法,把这一个吃透,再看我圈中的方法就很简答了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值