【四】Spring IoC 最全源码详解之 invokeBeanFactoryPostProcessors与ConfigurationClassPostProcessor扫包

本文深入解析Spring IoC的`refresh()`方法中`invokeBeanFactoryPostProcessors()`的执行流程,尤其是ConfigurationClassPostProcessor如何扫包和回调配置类。内容涵盖PriorityOrdered接口的回调、Ordered接口回调、BeanDefinitionRegistryPostProcessors的执行以及其他BeanFactoryPostProcessor的回调。文章详细介绍了扫包的各个阶段,包括根路径获取、资源查找、文件扫描等,是理解Spring启动流程的关键。
摘要由CSDN通过智能技术生成

地球形成                   距今46亿年
地球冷却形成地壳    距今39亿年~25亿年
生命出现            距今35亿年前
细菌的出现          距今30亿年前
光合作用            距今20亿年前
多细胞生物          距今16亿年前
生命登上陆地        距今5亿年前
鱼类出现            距今5亿年前
植物出现            距今4亿年前
两栖类出现          距今3亿年前
爬虫类出现          距今2.4亿年
哺乳类出现          距今2亿年前
鸟类出现            距今1.3亿年前
灵长类出现          距今4000万年
猿与黑猩猩谱系分离  距今3000万年
南方古猿出现        距今350万年
尼安德特人消失      距今12万年前
金字塔修建          距今2700年
秦始皇统一中国      公元前221
大清亡了            距今107年

阅读本文大致需要4小时,比起上述这些时间又算得了什么呢。

目录

1.  获取配置类和执行其回调

1.1 对实现了PriorityOrdered.class接口的BeanFactoryPostProcessor进行回调方法的执行

1.2 方法回调

1.2.1 获取根路径

1.2.2 扫包

1.2.3 getResources

2. 对实现了Ordered.class接口的BeanFactoryPostProcessor进行回调方法的执行

3.  对其他BeanDefinitionRegistryPostProcessors回调方法的执行。

4. 执行其他BeanFactoryPostProcessor的回调


本节将介绍refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory)方法。该方法主要进行BeanFactoryPostProcessors方法的注册和对应回调方法的执行。核心方法是

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

它非常长,我们分以下几个部分进行详细介绍。

1.  获取配置类和执行其回调

    入参List<BeanFactoryPostProcessor> beanFactoryPostProcessors是通过getBeanFactoryPostProcessors()获取已经注册到Spring的BeanFactoryPostProcessor。显然在本步骤之前是没有BeanFactoryPostProcessor被注册的,不然refresh调用invokeBeanFactoryPostProcessors方法不是多此一举吗?

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	Set<String> processedBeans = new HashSet<>();
	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		// 入参beanFactoryPostProcessors是获取的bean工厂List<BeanFactoryPostProcessor> beanFactoryPostProcessors中提前被注册好的postProcessors
		// 这里因为项目中并未实现BeanFactoryPostProcessor接口,故循环不会进入。
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				regularPostProcessors.add(postProcessor);
			}
		}

		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// postProcessorNames: internalConfigurationAnnotationProcessor, 他实现了BeanFactoryPostProcessor接口
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

		// 第一步,根据后置处理器名字判断是否实现了PriorityOrdered接口
		for (String ppName : postProcessorNames) {			
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 1.beanFactory.getBean(xx,xx)方法是实例化对象,然后将其添加进bean工厂中交给Spring管理
				// 2 将该bean放入到List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors中
				// 3.最终实例化的对象类型是ConfigurationClassPostProcessor.class
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);

		//利用ConfigurationClassPostProcessor处理器对项目的配置类进行解析。
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

1.1 对实现了PriorityOrdered.class接口的BeanFactoryPostProcessor进行回调方法的执行

beanFactoryPostProcessors为null意味着第一个for循环直接跳过。第一个有价值的代码是:

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

getBeanNamesForType ==> doGetBeanNamesForType,进入到doGetBeanNamesForType方法中,

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    List<String> result = new ArrayList<>();

    for (String beanName : this.beanDefinitionNames) {
        // 只使用大名
        if (!isAlias(beanName)) {
            //为了节约篇幅,去掉了try..catch..块
            RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);            
            if (!mbd.isAbstract() && (allowEagerInit ||
                    (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                            !requiresEagerInitForType(mbd.getFactoryBeanName()))) {                
                boolean isFactoryBean = isFactoryBean(beanName, mbd);
                BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                boolean matchFound =
                        (allowEagerInit || !isFactoryBean ||
                                (dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
                        (includeNonSingletons ||
                                (dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
                        isTypeMatch(beanName, type);
                //如果没匹配到,但该bean又是FactoryBean,则按照FactoryBean的规则在beanName前加上'&',用新的名字再找一次
                if (!matchFound && isFactoryBean) {
                    beanName = FACTORY_BEAN_PREFIX + beanName;
                    matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
                }
                //找到了,就将其加入到resute的List中
                if (matchFound) {
                    result.add(beanName);
                }
            }            
        }
    }

    // 在"environment", "systemProperties","systemEnvironment" 中进行寻找
    for (String beanName : this.manualSingletonNames) {
        if (isFactoryBean(beanName)) {
            if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
                result.add(beanName);
                continue;
            }
            beanName = FACTORY_BEAN_PREFIX + beanName;
        }
        // 判断名为beanName的bean是否是type类型
        if (isTypeMatch(beanName, type)) {
            result.add(beanName);
        }
    }

    return StringUtils.toStringArray(result);
}

首先是遍历List<String> beanDefinitionNames,从以下候选项中找出符合条件的bdName添加到result中。

0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
3 = "org.springframework.context.event.internalEventListenerProcessor"
4 = "org.springframework.context.event.internalEventListenerFactory"
5 = "caseApplication"

然后再从手动添加的那三个"environment", "systemProperties","systemEnvironment" beanName中寻找除满足要求的beanName也添加到result中。最终找寻的结果只有一个,internalConfigurationAnnotationProcessor,这个玩意是事先就注册进去的。具体何时注册和怎么注册,请参考本系列文章《【二】Spring IoC 最全源码详解之 register》详细分析。

for (String ppName : postProcessorNames) {			
	if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
		// 1.beanFactory.getBean(xx,xx)方法是实例化对象,然后将其添加进bean工厂中交给Spring管理
		// 2 将该bean放入到List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors中
		// 3.最终实例化的对象类型是ConfigurationClassPostProcessor.class
		currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
		processedBeans.add(ppName);
	}
}
//这里currentRegistryProcessors里面就一个值,还排个卵
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);

获取String[] postProcessorNames之后紧接着就执行BeanFactoryPostProcessor注册操作。因为ConfigurationClassPostProcessor实现了PriorityOrdered接口。所以typeToMatch.isAssignableFrom(beanType)的执行结果是true。落入if块中,beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)是将名字为ppName的后置处理实例化出来放入bean工厂中。随后再将该后置处理器对象放入List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors中。实例化过程不是本节的重点内容,后续再讲。isTypeMatch里面的很难,简单进行分析并注释如下,就不占用大量篇幅介绍了。

public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
    //如果是普通的bean则beanName不变,如果是FactroyBean,则去掉前缀'&'
    String beanName = transformedBeanName(name);

    // 这里高能,不好理解。见代码块下方提示。
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
        dosomething();        
    }

    //如果bean工厂中singletonObjects容器中含有该对象,但是bdmap中却不存在,说明是其他线程正在并发执行移除bean的流程。故不能再将移除的bd再进行注册了。
    else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
        // null instance registered
        return false;
    }

    // 我们就用了默认的bean工厂,从未自己实现过自己的bean工厂,并且还将其作为Spring默认bean工厂的父类,故这里也不会进
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值