【Spring源码解读三】IoC容器之AnnotationConfigApplication的refresh()刷新方法其二

news2024/11/27 7:33:33

invokeBeanFactoryPostProcessors()

PriorityOrdered接口

Ordered接口

invokeBeanDefinitionRegistryPostProcessors()

registerBeanPostProcessors()

getBeanNamesForType()

initMessageSource()

initApplicationEventMulticaster()

onRefresh()

registerListeners()

finishBeanFactoryInitialization()

finishRefresh()

参考文献


上个博文已经记录了refresh()的前四个方法作用,也就是

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// 刷新上下文
		prepareRefresh();

		// 告诉子类刷新内部 Bean工厂
        // 在这个方法中主要是获取 DefaultListableBeanFactory 这个Bean工厂
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// 准备Bean工厂以便在此上下文中使用
		prepareBeanFactory(beanFactory);

		try {
			// 允许在上下文子类中对bean工厂进行后处理
			postProcessBeanFactory(beanFactory);

            // 这篇博文主要先记录后八个步骤

			// 调用在上下文中注册为bean的工厂处理器(重要)
            // 注解开发对包进行扫描得到Bean的定义
			invokeBeanFactoryPostProcessors(beanFactory);

            // 注册拦截bean创建的bean处理器 如果没有BeanProcessors 此步骤什么也不做
			registerBeanPostProcessors(beanFactory);

			// 初始化此上下文的消息源
            // 将messageSource这个Bean对象放到beanFactory中的singletonObjects中
			initMessageSource();

			// 初始化此上下文的事件多播
            // 将applicationEventMulticaster这个Bean对象放到beanFactory中的singletonObjects中
			initApplicationEventMulticaster();

			// 初始化特定上下文子类中的其他特殊bean
			onRefresh();

			// 检查侦听器bean并注册它们
            // 在所有Bean中查找Listener这个Bean对象并注册到消息广播中 没有的话什么也不做
			registerListeners();

			// 实例化所有剩余的(非惰性初始化)单例  重要
			finishBeanFactoryInitialization(beanFactory);

			// 初始化并刷新生命周期处理器
			finishRefresh();
		} catch (BeansException ex) {
			if (logger.isWarnEnabled()) {
				logger.warn("Exception encountered during context initialization - " +
						"cancelling refresh attempt: " + ex);
			}

			// 销毁已创建的singleton以避免挂起资源
			destroyBeans();

			// 重置“活动”标志
			cancelRefresh(ex);

			// 向调用方传播异常
			throw ex;
		} finally {
			// 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例bean的元数据
			resetCommonCaches();
		}
	}
}

invokeBeanFactoryPostProcessors()

        这里主要去看PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法,此方法内部主要是调用Bean工厂的后置处理器发挥作用。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// 调用Bean工厂的后置处理器发挥作用 接下来进入这个方法的源码中阅读
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
 
	// 检测LoadTimeWeaver并准备编织(如果同时发现)
	// 例如,通过ConfigurationClassPostProcessor注册的@Bean方法) 
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

        进入这个方法首先需要知道两个接口。第一个是BeanFactoryPostProcessor:用来修改Spring容器中已经存在的bean的定义,使用ConfigurableListableBeanFactory对bean进行处理。第二个是BeanDefinitionRegistryPostProcessor:继承BeanFactoryPostProcessor,作用跟BeanFactoryPostProcessor一样,只不过是使用BeanDefinitionRegistry对bean进行处理。

以下六步是这个方法内部的实现逻辑。

        第一步是实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor找出来,然后排序后依次执行;

        第二步是实现Ordered接口的BeanDefinitionRegistryPostProcessor找出来,然后排序后依次执行;

        第三步是实现其它接口的BeanDefinitionRegistryPostProcessor找出来执行并依次执行。

        第三步是实现PriorityOrdered接口的BeanFactoryPostProcessor找出来,然后排序后依次执行;

        第四步是实现Ordered接口的BeanFactoryPostProcessor找出来,然后排序后依次执行;

        第五步是实现其它接口的BeanFactoryPostProcessor找出来执行并依次执行。

        第六步是清除缓存clearMetadataCache()。

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		// 存放Bean工厂后置处理器的链表
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		// 存放Bean描述注册后置处理器的链表
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		// 遍历存放Bean工厂后置处理器的链表
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			} else {
				regularPostProcessors.add(postProcessor);
			}
		}

		// 这里不要初始化FactoryBeans:我们需要保持所有常规bean未初始化,以便让bean工厂的后处理器应用于它们!
		// 在实现PriorityOrdered、Ordered和其他的BeanDefinitionRegistryPostProcessors之间分离。
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessors。
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		// 在调试时返回的postProcessorNames是org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory); // 排序
		registryProcessors.addAll(currentRegistryProcessors); // 将第二个存放BeanDefinitionRegistryPostProcessor的链表的元素放到第一个链表中
        // 调用PostProcessors 此方法会在下面进行介绍
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear(); // 清空currentRegistryProcessors链表

		// 其次,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			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);
		currentRegistryProcessors.clear();

		// 最后,调用所有其他BeanDefinitionRegistryPostProcessors,直到不再出现其他处理器为止
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
					reiterate = true;
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}

		// 现在,调用迄今为止处理的所有处理器的postProcessBeanFactory回调
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	} else {
		// 调用在上下文实例中注册的工厂处理程序
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// 这里不要初始化FactoryBeans:我们需要保持所有常规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)) {
			// 跳过-已在上面的第一阶段中处理
		} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		} else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	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);
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// 最后,调用其它所有的BeanFactoryPostProcessors
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	// 清除缓存的合并bean定义,因为后处理程序可能已经修改了原始元数据,例如替换了值中的占位符
	// 1、将AbstractBeanFactory的mergedBeanDefinitions(Map)其中的值RootBeanDefinition中的stale设为true
	// 2、将DefaultListableBeanFactory的mergedBeanDefinitionHolders、allBeanNamesByType、singletonBeanNamesByType三个Map集合清空
	beanFactory.clearMetadataCache();
}

        这里我认为需要做笔记学习一下PriorityOrdered接口与Ordered接口的作用。

PriorityOrdered接口

        PriorityOrdered接口源码没有方法,只是实现了Ordered接口。并且有很多类实现了这个接口。

public interface PriorityOrdered extends Ordered {
}

Ordered接口

        Ordered接口源码,很简短,就定义了一个Ordered接口,然后两个常量,分别对应最高级(数值最小)和最低级(数值最大),也就是数值越小,等级越高,数值越大,等级越低,然后有一个getOrder()方法返回排序值。

        这个接口主要是配合@Order注解。两者的作用是定义Spring IOC容器中Bean的执行顺序的优先级,Bean的加载顺序不受@Order或Ordered接口的影响;而Ordered接口,用来排序的。Spring是一个大量使用策略设计模式的框架,这意味着有很多相同接口的实现类,那么必定会有优先级的问题。于是,Spring就提供了Ordered这个接口,来处理相同接口实现类的优先级问题。getOrder()值越小,优先级越高。一般用于AOP事务执行顺序

public interface Ordered {

	// 用于最高优先级值的有用常量
	int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

	// 用于最低优先级值的有用常量
	int LOWEST_PRECEDENCE = Integer.MAX_VALUE;


	/**
	 * 获取该对象的order值。
	 * <p>较高的值被解释为较低的优先级。作为结果,
	 * 值最低的对象具有最高优先级(有点
	 * 类似于Servlet {@ code-on-startup}值)。
     * <p>相同的order值将导致受影响的对象任意排序位置
     * @return 排序值
	 * @see #HIGHEST_PRECEDENCE
	 * @see #LOWEST_PRECEDENCE
	 */
	int getOrder();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {

	// Order的值
	int value() default Ordered.LOWEST_PRECEDENCE;
}

invokeBeanDefinitionRegistryPostProcessors()

        接下来就先看这个方法的最后一行,也就是实际处理配置类Bean定义的方法。由于其源码太多就不copy出来了,主要是对配置类的注解进行处理处理配置类的Bean的定义,将配置类中的Bean放置BeanDefinitionRegistry下的beanDefinitionMap中。

/**
 * 调用给定的BeanFactoryPostProcessor bean。
 */
private static void invokeBeanFactoryPostProcessors(
		Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

	for (BeanFactoryPostProcessor postProcessor : postProcessors) {
		postProcessor.postProcessBeanFactory(beanFactory);
	}
}

// 紧接着调用父类BeanDefinitionRegistryPostProcessor的方法
// 其有多个实现类 但是进入到了ConfigurationClassPostProcessor类进行实现
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)) {
		// 主要是看这个方法
		processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
	}
	enhanceConfigurationClasses(beanFactory);
	beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

/**
 * 从注册表中的配置类派生更多的bean定义。
 */
@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);
}

registerBeanPostProcessors()

        注册拦截bean创建的bean处理器。在这里面主要是做了三件事情。

1、先找出实现了PriorityOrdered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中。

2、找出实现了Ordered接口的BeanPostProcessor并排序后加到BeanFactory的BeanPostProcessor集合中。

3、没有实现PriorityOrdered和Ordered接口的BeanPostProcessor加到BeanFactory的BeanPostProcessor集合中。

/**
 * 实例化并注册所有BeanPostProcessor bean,如果给定,则遵循显式顺序。
 * 必须在应用程序bean的任何实例化之前调用。
 */
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

public static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 此方法会在下面进行介绍
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// 注册BeanPostProcessorChecker,当在BeanPostProcessor实例化期间创建bean时,即当bean不适合由所有BeanPostProcessors处理时,该Checker会记录信息消息
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// 在实现PriorityOrdered、Ordered和其他的BeanPostProcessors之间分离。
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	List<String> orderedPostProcessorNames = new ArrayList<>();
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		} else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// 首先,注册实现PriorityOrdered的BeanPostProcessors。
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// 接下来,注册实现Ordered的BeanPostProcessors。
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// 现在,注册所有常规BeanPostProcessors。
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// 最后,重新注册所有内部BeanPostProcessors。
	sortPostProcessors(internalPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, internalPostProcessors);

	// 将用于检测内部bean的后处理器重新注册为ApplicationListeners,将其移动到处理器链的末端(用于拾取代理等)。
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

getBeanNamesForType()

        从上面PostProcessorRegistrationDelegate类的registerBeanPostProcessors()方法中,第一行代码就是进入getBeanNamesForType()方法,而这个方法是由几个实现类实现的,而基于前面IoC容器刷新的第二个方法中就是获取DefaultListableBeanFactory这个对象。所以会进入到这个类。先看结果:获取到了internalAutowiredAnnotationProcessorinternalCommonAnnotationProcessor这两个对象。下面的截图就是beanDefinitionNames列表中的值。

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

	// 检查所有bean定义
	for (String beanName : this.beanDefinitionNames) {
		// 只有当bean名称没有定义为其他bean的别名时,才认为bean是合格的
		if (!isAlias(beanName)) {
			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 只有在bean定义完成时才检查它
				if (!mbd.isAbstract() && (allowEagerInit ||
						(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
								!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
					boolean isFactoryBean = isFactoryBean(beanName, mbd);
					BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
					boolean matchFound = false;
					boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
					boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
					if (!isFactoryBean) {
						if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					} else  {
						if (includeNonSingletons || isNonLazyDecorated ||
								(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
						if (!matchFound) {
							// 在FactoryBean的情况下,接下来尝试匹配FactoryBean实例本身
							beanName = FACTORY_BEAN_PREFIX + beanName;
							matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
						}
					}
					if (matchFound) {
						result.add(beanName);
					}
				}
			} catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
				if (allowEagerInit) {
					throw ex;
				}
				// 可能是一个占位符:出于类型匹配的目的,让我们忽略它
				LogMessage message = (ex instanceof CannotLoadBeanClassException) ?
						LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
						LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName);
				logger.trace(message, ex);
				onSuppressedException(ex);
			}
		}
	}
}

initMessageSource()

        初始化MessageSource组件(做国际化功能;消息绑定,消息解析),这个接口提供了消息处理功能。主要用于国际化/i18n。在这方法中主要是在上下文初始化注册、messageSource的Bean。将此Bean对象放到beanFactory的singletonObjects对象中。

/**
 * 工厂中 MessageSource bean的名称。
 * 如果未提供,则将消息解析委派给父级。
 * @see MessageSource
 */
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

/**
 * 初始化MessageSource。如果在此上下文中未定义,请使用父级的。
 */
protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// 使MessageSource知道父MessageSource
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				// 如果尚未注册任何父MessageSource,则仅将父上下文设置为父MessageSource。
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Using MessageSource [" + this.messageSource + "]");
		}
	} else {
		// 使用空的MessageSource可以接受getMessage调用。
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
        // 在这步将messageSource这个Bean对象放到beanFactory中的singletonObjects中
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
		}
	}
}

initApplicationEventMulticaster()

        在这方法中主要是在上下文初始化注册AppplcationEventMulticaster的Bean。应用消息广播。将此Bean对象放到beanFactory的singletonObjects对象中。

protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster =
				beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		if (logger.isTraceEnabled()) {
			logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
		}
	} else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		if (logger.isTraceEnabled()) {
			logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
					"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
		}
	}
}

onRefresh()

protected void onRefresh() throws BeansException {
	// 对于子类中才进行操作 否则默认情况下不执行任何操作
}

registerListeners()

protected void registerListeners() {

	// 首先注册静态指定的侦听器
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// 不要在这里初始化FactoryBeans:我们需要保持所有常规bean未初始化,以便让后处理器应用于它们!
	String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
	for (String listenerBeanName : listenerBeanNames) {
		getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
	}

	// 发布早期的应用程序事件,现在我们终于有了多主机
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

finishBeanFactoryInitialization()

        由于这个方法内的源码较多,可以先看这个方法执行结束后在beanFactory的singletonObjects中存放了什么对象,可以看到存放了在配置类中定义的bean对象(user)。我打算将这个方法的源码放到下一个文章在进行描述。

finishRefresh()

protected void finishRefresh() {
	// 清除上下文级资源缓存(如扫描中的ASM元数据)
    // 对应的就是resourceCaches这个ConcurrentHashMap的清空
	clearResourceCaches();

	// 初始化此上下文的生命周期处理器
	initLifecycleProcessor();

	// 首先将刷新传播到生命周期处理器
	getLifecycleProcessor().onRefresh();

	// 发布最终事件
	publishEvent(new ContextRefreshedEvent(this));

	// 参与LiveBeansView MBean(如果活动)
	LiveBeansView.registerApplicationContext(this);
}

        以上就是refresh()方法的后八个方法的源码剖析,当然,并没有那么深度的进行剖析,毕竟本人水平有限,再加上太深度的剖析会导致文字量太大。还有个finishBeanFactoryInitialization()方法,也就是try语句块的倒数第二个方法,就放到下一篇博文了。

参考文献

Spring5 IOC容器解析——refresh()方法分析_小波同学的技术博客_51CTO博客

https://www.cnblogs.com/dabo-tian/p/16454375.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/629144.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

听我一句劝,别去外包,干了三年,真废了....

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…

找不到xinput1_3.dll怎么办?xinput1_3.dll丢失的四个修复方法

在我们打开游戏的或者软件的时候&#xff0c;电脑提示“找不到xinput1_3.dll&#xff0c;无法继续执行此代码”怎么办&#xff1f;相信困扰着不少小伙伴&#xff0c;我再在打开吃鸡的时候&#xff0c;然后花了一上午的时候时间研究&#xff0c;现在终于知道xinput1_3.dll文件是…

Windows10系统开启 Telnet客户端 功能

1、应用场景 在实际工作中&#xff0c;经常有查看机器端口连通性的场景&#xff08;主要为了确认某台机器上的服务是否正常&#xff0c;比如&#xff1a;查看的端口 9091&#xff09; telnet 192.168.166.159 9091如下状态说明telnet 端口是通的 Ctrl ] ,退出Telnet连接&a…

探究Vue源码:mustache模板引擎(2) mustache使用方法

mustache是最早的模板引擎 比vue的诞生还要早很多 而他的语法 就是基于 {{ }} 这样的双花括号 mustache属于通用性的应用 他既可以在浏览器中直接用 也可以在npm中使用 这里 我们为了方便 就直接去拿在浏览器中使用的包了 没必要再自己搭个环境 大家可以下载我上传的资源 vue源…

职场老油条表示真干不过,部门新来的00后测试员已把我卷崩溃,想离职了...

在程序员职场上&#xff0c;什么样的人最让人反感呢? 是技术不好的人吗?并不是。技术不好的同事&#xff0c;我们可以帮他。 是技术太强的人吗?也不是。技术很强的同事&#xff0c;可遇不可求&#xff0c;向他学习还来不及呢。 真正让人反感的&#xff0c;是技术平平&#x…

Linux学习之vim正常模式和插入模式

使用vim新建或者打开一个文件后&#xff0c;首先进入的就是正常模式&#xff0c;从正常模式按不同的按键能够进入其他三种模式。 在正常模式下&#xff0c;按i&#xff0c;I&#xff08;大写的i键&#xff09;&#xff0c;a&#xff0c;A&#xff0c;o&#xff08;小写的o&…

【3DsMAX】从零开始建房(6)

目录 1. 制作广告牌 2. 制作屋顶小船船身 1. 制作广告牌 先创建一个长方体 转换为可编辑多边形&#xff0c;选中面&#xff0c;插入 挤出 添加两个圆柱体作为支架 用轮廓工具收一下面 选中这三个物体打组 统一材质 设置线条颜色为黑色 2. 制作屋顶小船船身 先添加一个球体&…

顺序表刷题(1~3)

目录 移除元素 删除有序数组重复项 合并有序数组 移除元素 方法一&#xff1a; 如果找到一个删除一个这样的时间复杂度为O(n^2)&#xff08;最坏删除所有数据&#xff09;删除后还要挪动数据。我们可以将符合条件的数组元素放入一个临时数组中&#xff0c;这种方法的时间复杂…

什么是数据结构

一、什么是数据结构 1、数据结构的定义 数据&#xff1a;从计算机的角度来看&#xff0c;数据是所有能被输入到计算机中且能被计算机处理的符号的集合。它是计算机操作的对象的总称&#xff0c;也是计算机处理信息的某种特定的符号表示形式&#xff08;二进制码的抽象表示&am…

【高级篇】服务异步通信

服务异步通信-高级篇 消息队列在使用过程中&#xff0c;面临着很多实际问题需要思考&#xff1a; 1.消息可靠性 消息从发送&#xff0c;到消费者接收&#xff0c;会经理多个过程&#xff1a; 其中的每一步都可能导致消息丢失&#xff0c;常见的丢失原因包括&#xff1a; 发送…

030 JavaWeb Html CSS

目录 JavaWeb概述1.访问web的原理2.C/S软件和B/S软件区别3.静态网站和动态网站 HTMLHTML的概述Table表格详细用法见W3CSchool.chm合并单元格课程表 img标签table和img标签组合使用a标签表单表单Get提交和post提交 div和span CSS1.CSS概述2.CSS语法3.CSS三种写法行内样式内部样式…

VueX使用简明笔记

1、作用&#xff1a; vuex是使用vue中必不可少的一部分&#xff0c;基于父子、兄弟组件&#xff0c;我们传值可能会很方便&#xff0c;但是如果是没有关联的组件之间要使用同一组数据&#xff0c;就显得很无能为力&#xff0c;那么vuex就很好的解决了我们这种问题&#xff0c;…

Knife4j的使用、SpringFox和SpringDoc介绍

knife4j是一个Swagger的增强工具&#xff0c;能够完善项目的接口文档。 官网&#xff1a; Knife4j 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j Swagger的生成的默认文档确实不好用&#xff08;不美观、不支持搜索、不能导出&#xff09; 在Swagger2中使用 想一想…

Android 12.0 原生SystemUI下拉通知栏每条通知默认展开

1.前言 在12.0的系统rom原生开发中,在在对SystemUI下拉通知栏做定制的时候,在下拉状态栏的时候,通知栏中 最后一条通知默认是收缩的 点击按钮 就会展开 原生系统systemui就是如此,为了更美观 所以要求最后一条通知也默认展开,显得更美观 最终效果图: 2.原生SystemUI下拉通…

C++/C按照时间命名保存bin文件

背景 在Linux应用编程过程中&#xff0c;使用C或者C语言保存、读取bin文件是比较常见的需求。这里详细记录一下使用C保存bin文件&#xff0c;也可以使用C语言实现。 代码 C/C语言保存bin文件函数&#xff0c;C中也能使用 正确写入返回0&#xff0c;错误返回-1 // C 保存bi…

双重检查锁定与延迟初始化

双重检查锁定的由来 在Java程序中&#xff0c;有时候可能需要推迟一些高开销的对象初始化操作&#xff0c;并且只有在使用这些对象时才进行初始化。此时&#xff0c;程序员可能会采用延迟初始化。但要正确实现线程安全的延迟初始化需要一些技巧&#xff0c;否则很容易出现问题…

51单片机操作系统——RTX51 Tiny

简介 RTX51 是keil公司开发的一款实时操作系统&#xff0c;其有两个版本&#xff1a; 1.Tiny 2.Full&#xff0c;区别如下&#xff1a; RTX51 Full &#xff1a;使用四个任务优先权完成同时存在时间片轮转调度和抢先的任务切换 RTX51工作与中断功能相似的状态下 &#xff0c…

华为OD机试真题 JavaScript 实现【最远足迹】【2022Q4 100分】,附详细解题思路

一、题目描述 某探险队负责对地下洞穴进行探险。探险队成员在进行探险任务时&#xff0c;随身携带的记录器会不定期地记录自身的坐标&#xff0c;但在记录的间隙中也会记录其他数据。探索工作结束后&#xff0c;探险队需要获取到某成员在探险过程中相对于探险队总部的最远的足…

【打卡】苹果叶片病害分类和建筑物变化检测数据挖掘竞赛

【打卡】苹果叶片病害分类和建筑物变化检测数据挖掘竞赛 文章目录 【打卡】苹果叶片病害分类和建筑物变化检测数据挖掘竞赛Task 1两个赛题数据可视化任务2 苹果病害数据加载与数据增强任务三 Task 1两个赛题数据可视化 在这个任务中&#xff0c;参赛选手需要对两个赛题的数据进…

卡奥斯开源社区六月创作之星挑战赛开始啦!

活动须知 发布优质文章争榜&#xff0c;获取专属勋章、流量扶持及奖励&#xff01; 活动时间&#xff1a;6 月 1 日- 6 月 30 日 奖品发放&#xff1a;7月10日 参与方式 完成认证发布优质文章&#xff0c;选中相关活动标签&#xff0c;文章默认参与活动 文章要求 文章符合…