前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring读源码系列08----容器扩展功能--下

Spring读源码系列08----容器扩展功能--下

作者头像
大忽悠爱学习
发布2022-05-10 16:28:02
3370
发布2022-05-10 16:28:02
举报
文章被收录于专栏:c++与qt学习

Spring读源码系列08----容器扩展功能--下


注册BeanPostProcessor

前两篇文章已经讲述完了refresh方法中一部分的步骤,今天这篇文章就结束该方法的讲解,那么先从registerBeanPostProcessors方法讲起吧

代码语言:javascript
复制
	@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.
			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();
				....

registerBeanPostProcessors

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

可以看到具体执行过程是委托给了PostProcessorRegistrationDelegate完成的,这是一种很好的重构思想,大家可以学习一下,当然不是任何情况下都需要进行重构,而是考虑到代码量和当前代码与当前类的相关度情况下进行决策的

该代理类的registerBeanPostProcessors方法在上一篇文章中已经讲过了,下面我再贴出来一遍作为巩固:

Spring读源码系列07----容器扩展功能–中


PostProcessorRegistrationDelegate#registerBeanPostProcessors

代码语言:javascript
复制
//注册拦截 bean 创建的 bean 处理器。
public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

//警告:虽然看起来可以轻松地重构此方法的主体以避免使用多个循环和多个列表,
//但使用多个列表和多次传递处理器名称是有意的。
//我们必须确保我们遵守 PriorityOrdered 和 Ordered 处理器的合同。
//具体来说,我们不能导致处理器被实例化(通过 getBean() 调用)或以错误的顺序在 ApplicationContext 中注册。
      
//拿到容器中所有实现了BeanPostProcessor接口的bean
		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

//注册 BeanPostProcessorChecker,
//它会在 BeanPostProcessor 实例化期间创建 bean 时记录一条信息消息,
//即当 bean 不符合所有 BeanPostProcessor 处理的条件时。
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        //分别处理实现了priorityOrdered,ordered和啥都没有实现的以及内部使用的bean的后置处理器
		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		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);
				//MergedBeanDefinitionPostProcessor---合并bean的定义
				//例如: AutowiredAnnotationBeanPostProcessor处理autowired注解
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

        //先处理PriorityOrdered,然后注册
		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        //再处理oreder接口
		// Next, register the BeanPostProcessors that implement Ordered.
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			//判断是否是MergedBeanDefinitionPostProcessor
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		//处理没有实现任何优先级接口的bean
		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);

		// Finally, re-register all internal BeanPostProcessors.
		//再处理internalPostProcessors即MergedBeanDefinitionPostProcessor集合
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		//添加一个ApplicationListenerDetector后置处理器到处理器链尾部
		//在refresh的prepareBeanFactory方法中已经添加过该后置处理器,这里是为了把他移动到处理器链尾部
		//为啥要那么麻烦搞两次,这个应该有其自身原因
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
代码语言:javascript
复制
	private static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

		if (beanFactory instanceof AbstractBeanFactory) {
			// Bulk addition is more efficient against our CopyOnWriteArrayList there
			((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
		}
		else {
			for (BeanPostProcessor postProcessor : postProcessors) {
				beanFactory.addBeanPostProcessor(postProcessor);
			}
		}
	}

可以看到prepareBeanFactory方法中就已经注册过了


初始化消息资源

代码语言:javascript
复制
	@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.
			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();
...

initMessageSource

这里关于消息国际化部分,不是本文重点,但是又不想直接跳过,因此我就直接把书上对应部分内容拿了过来

代码语言:javascript
复制
	/**
	 * Initialize the MessageSource.
	 * Use parent's if none defined in this context.
	 */
	protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//MESSAGE_SOURCE_BEAN_NAME--->messageSource
		//说明消息数据源的beanName必须是messageSource
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			//如果上面没找到,那么不会进行下面这个分支条件
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
		//容器中不存在messageSource的bean,那么创建一个默认的DelegatingMessageSource
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			//注册这个默认创建的DelegatingMessageSource
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
			}
		}
	}

MessageSource在哪里被使用呢?

代码语言:javascript
复制
	@Override
	public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
		return getMessageSource().getMessage(code, args, defaultMessage, locale);
	}

具体使用就如下了:

这里国际化就到此结束了,因为国际化目前使用较少,因此这里就小篇幅就讲解了,我们把重心放在更加重要的组件上面


初始化ApplicationEventMulticaster

代码语言:javascript
复制
	@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.
			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();
				...

使用场景演示

在正式讲解spring的事件派发器前,还是先来复习一下spring的事件监听器的使用

  • 定义监听事件
代码语言:javascript
复制
public class TestEvent extends ApplicationEvent {
    private Object source;
    
    public TestEvent(Object source) {
        super(source);
        this.source=source;
    }
    
    public void processObj()
    {
        System.out.println("TestEvent当前正在处理的事件为: "+source);
    }
}
  • 定义监听器
代码语言:javascript
复制
public class TestListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if(event instanceof TestEvent)
        {
            TestEvent testEvent = (TestEvent) event;
            testEvent.processObj();
        }
    }
}
  • 监听器注入容器—后置处理器自动识别(ApplicationListenerDetector)
代码语言:javascript
复制
<bean class="org.test.TestListener"/>
  • 测试
代码语言:javascript
复制
public class MainTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext xmlApplicationContext = new ClassPathXmlApplicationContext("bean.xml");
        xmlApplicationContext.publishEvent(new TestEvent("我是消息"));
    }
}


initApplicationEventMulticaster

代码语言:javascript
复制
	protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//APPLICATION_EVENT_MULTICASTER_BEAN_NAME-->applicationEventMulticaster
		//和messagesource一样,bean的名字是固定不变的
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		//如果容器中存在用户自定义的applicationEventMulticaster,那么就使用用户注入的
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
		//否则使用默认的SimpleApplicationEventMulticaster
			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() + "]");
			}
		}
	}

SimpleApplicationEventMulticaster内部如何派发事件的

废话不多说,咱们上源码:

代码语言:javascript
复制
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

	@Nullable
	private Executor taskExecutor;

	@Nullable
	private ErrorHandler errorHandler;

	@Nullable
	private volatile Log lazyLogger;

	public SimpleApplicationEventMulticaster() {
	}

	public SimpleApplicationEventMulticaster(BeanFactory beanFactory) {
		setBeanFactory(beanFactory);
	}


	@Override
	public void multicastEvent(ApplicationEvent event) {
		multicastEvent(event, resolveDefaultEventType(event));
	}

	@Override
	public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
	//先拿到发布事件的类型信息
		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
	//获取到任务执行器---默认不会设置,为null,如果想让监听器完成异步执行,可以进行手动设置,默认为同步	
		Executor executor = getTaskExecutor();
		//getApplicationListeners返回与给定事件类型匹配的 ApplicationListener 的集合。不匹配的听众会提前被排除在外。
		//SmartApplicationListener继承了ApplicationListener 接口,并且本身也是接口
		//但是它多了一个supportsEventType和supportsSourceType方法用来判断当前监听器是否支持当前事件
		//因此这里getApplicationListeners方法的逻辑并没有大家想的那么简单,感兴趣的小伙伴可以自行研究
		for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
			if (executor != null) {
				//这里手动设置执行器,可以让监听者在单独的线程中处理发生的事件,而不是同步执行
				executor.execute(() -> invokeListener(listener, event));
			}
			else {
			//默认同步触发监听者来挨个处理事件
				invokeListener(listener, event);
			}
		}
	}
	
	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
		ErrorHandler errorHandler = getErrorHandler();
		if (errorHandler != null) {
			try {
			//真正逻辑被重构到doInvokeListener函数中
				doInvokeListener(listener, event);
			}
			catch (Throwable err) {
				errorHandler.handleError(err);
			}
		}
		else {
			doInvokeListener(listener, event);
		}
	}

	@SuppressWarnings({"rawtypes", "unchecked"})
	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
		try {
		//最终调用的是监听器的onApplicationEvent方法
			listener.onApplicationEvent(event);
		}
		catch (ClassCastException ex) {
			String msg = ex.getMessage();
			if (msg == null || matchesClassCastMessage(msg, event.getClass()) ||
					(event instanceof PayloadApplicationEvent &&
							matchesClassCastMessage(msg, ((PayloadApplicationEvent) event).getPayload().getClass()))) {
				// Possibly a lambda-defined listener which we could not resolve the generic event type for
				// -> let's suppress the exception.
				Log loggerToUse = this.lazyLogger;
				if (loggerToUse == null) {
					loggerToUse = LogFactory.getLog(getClass());
					this.lazyLogger = loggerToUse;
				}
				if (loggerToUse.isTraceEnabled()) {
					loggerToUse.trace("Non-matching event type for listener: " + listener, ex);
				}
			}
			else {
				throw ex;
			}
		}
	}

...省略不重要的方法

}

通过这个默认实现,我们必须知道重要的一点,就是我们可以手动设置任务执行器来让事件被处理的过程处于异步状态


空实现onRefresh

AbstractApplicationContext:

代码语言:javascript
复制
	@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.
			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();
				...
代码语言:javascript
复制
//可以重写以添加特定于上下文的刷新工作的模板方法。在单例实例化之前调用特殊 bean 的初始化。
	protected void onRefresh() throws BeansException {
		// For subclasses: do nothing by default.
	}

向这种空实现方法,一方面是spring留个我们自定义发挥的空间,但是更多的时候是spring自己出于某种需求,需要这样做,因为一般都是spring内部其他applicationContext的子类重写该方法,并完成相对应的一些逻辑,所以大家不要以为没有用处


注册监听器

代码语言:javascript
复制
	@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.
			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();
				...

registerListeners

代码语言:javascript
复制
	/**
	 * Add beans that implement ApplicationListener as listeners.
	 * Doesn't affect other listeners, which can be added without being beans.
	 */
	protected void registerListeners() {
		// Register statically specified listeners first.
       //获取硬编码注册的监听器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
		//获取当然容器关联的事件派发器,默认为SimpleApplicationEventMulticaster
		//然后依次将已经存在的监听器注册进派发器中
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		//配置文件注册的监听器
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		//事件派发器也准备好了,监听器也都注册进去了,下一步查看是否存在早期事件有待处理
		//如果有的话,进行发布
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

初始化非延迟加载单例

代码语言:javascript
复制
	@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.
			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);
...

finishBeanFactoryInitialization

代码语言:javascript
复制
	/**
完成此上下文的 bean 工厂的初始化,初始化所有剩余的单例 bean。
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		//会自动识别容器中的CONVERSION_SERVICE,然后设置给当前beanFactory
		//但是这里也规定的CONVERSION_SERVICE的beanName必须为conversionService才可以
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no BeanFactoryPostProcessor
		// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		//如果没有设置内置的值解析器,就默认设置一个---用来解析占位符的
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		//LoadTimeWeaverAware是用来处理代理相关的东西,这里我还没去研究,展示不多介绍了
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		//为所有 bean 缓存 beanDefintion 元数据
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		//初始化所有剩余的单例 bean
		beanFactory.preInstantiateSingletons();
	}

freezeConfiguration

代码语言:javascript
复制
	@Override
	public void freezeConfiguration() {
		this.configurationFrozen = true;
		//在冻结配置的情况下缓存 bean 定义名称的数组。
		this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
	}

当我们要获取当前bean中存在的所有bean的beanName时:

代码语言:javascript
复制
	@Override
	public String[] getBeanDefinitionNames() {
		String[] frozenNames = this.frozenBeanDefinitionNames;
		if (frozenNames != null) {
			return frozenNames.clone();
		}
		else {
			return StringUtils.toStringArray(this.beanDefinitionNames);
		}
	}

当我们要注册一个新的bean定义时:

代码语言:javascript
复制
	public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
		Assert.hasText(beanName, "'beanName' must not be empty");

		BeanDefinition bd = this.beanDefinitionMap.remove(beanName);
		if (bd == null) {
			if (logger.isTraceEnabled()) {
				logger.trace("No bean named '" + beanName + "' found in " + this);
			}
			throw new NoSuchBeanDefinitionException(beanName);
		}

		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			synchronized (this.beanDefinitionMap) {
				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames);
				updatedDefinitions.remove(beanName);
				this.beanDefinitionNames = updatedDefinitions;
			}
		}
		else {
			// Still in startup registration phase
			this.beanDefinitionNames.remove(beanName);
		}
		//置空----不然数据不一致
		this.frozenBeanDefinitionNames = null;

		resetBeanDefinition(beanName);
	}

preInstantiateSingletons

我们必须知道一点: BeanFactory不会在初始化过程中,去创建好所有的bean实例,但是applicationContext会,那么这体现在哪里呢?—》就在下面

代码语言:javascript
复制
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		//拿到已经注册好的beanDefinitionNames集合副本
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//触发所有非懒加载的bean的实例化
		for (String beanName : beanNames) {
		//获取当前bean整合后的bean定义
		//其实和doGetBean方法流程一样,也是先通过getMergedLocalBeanDefinition方法拿到RootBeanDefinition 
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//bean不是抽象的并且是单例的,没有设置懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			//是否是工厂bean-->FactoryBean
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						//SmartFactoryBean继承了SmartFactoryBean
						//并且提供了一个isEagerInit方法来决定是否要较早初始化FactoryBean对象本身
						//然后再初始化getObject返回的bean实例来替换FactoryBean对象本身
						//确保BeanFactory的getBean返回的是getObject的返回值
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
					//如果为真
						if (isEagerInit) {
							//那么就提前初始化FactoryBean对象本身和getObject返回的bean实例
							getBean(beanName);
						}
					}
				}
				else {
				//对于非BeanFactory的普通bean来说,直接进行初始化即可
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		//为所有适用的 bean 触发初始化后回调...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			//如果当前bean实现了SmartInitializingSingleton接口的话
			if (singletonInstance instanceof SmartInitializingSingleton) {
				StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
						.tag("beanName", beanName);
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
				//会调用其afterSingletonsInstantiated方法
				//注意:实现了该接口的bean只会在applicationContext提前初始化的调用afterSingletonsInstantiated方法
					smartSingleton.afterSingletonsInstantiated();
				}
				smartInitialize.end();
			}
		}
	}

finishRefresh

代码语言:javascript
复制
	@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.
			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();
...

finishRefresh方法源码:

完成此上下文的刷新,调用 LifecycleProcessor 的 onRefresh() 方法并发布 ContextRefreshedEvent。

代码语言:javascript
复制
	protected void finishRefresh() {
		// Clear context-level resource caches (such as ASM metadata from scanning).
		//清除上下文级别的资源缓存(例如扫描中的 ASM 元数据)。
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
		//为此上下文初始化生命周期处理器。
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		//
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));

		// Participate in LiveBeansView MBean, if active.
		if (!NativeDetector.inNativeImage()) {
			LiveBeansView.registerApplicationContext(this);
		}
	}

initLifecycleProcessor

代码语言:javascript
复制
	/**
初始化生命周期处理器。
如果上下文中没有定义,则使用 DefaultLifecycleProcessor。
	 */
	protected void initLifecycleProcessor() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		//这里LifecycleProcessor的bean的名字是lifecycleProcessor
		if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
			this.lifecycleProcessor =
					beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
			if (logger.isTraceEnabled()) {
				logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
			}
		}
		else {
		//如果用户没有往容器中放入自定义的lifecycleProcessor,那么使用默认的DefaultLifecycleProcessor
			DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
			defaultProcessor.setBeanFactory(beanFactory);
			this.lifecycleProcessor = defaultProcessor;
			beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
			if (logger.isTraceEnabled()) {
				logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
						"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
			}
		}
	}

getLifecycleProcessor().onRefresh()

启动所有实现了Lifecycle接口的bean。

代码语言:javascript
复制
	@Override
	public void onRefresh() {
		startBeans(true);
		this.running = true;
	}
代码语言:javascript
复制
	private void startBeans(boolean autoStartupOnly) {
	//拿到容器中所有实现了Lifecycle接口的bean
		Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
		Map<Integer, LifecycleGroup> phases = new TreeMap<>();
         
		lifecycleBeans.forEach((beanName, bean) -> {
			if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) {
				int phase = getPhase(bean);
				phases.computeIfAbsent(
						phase,
						p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
				).add(beanName, bean);
			}
		});
		if (!phases.isEmpty()) {
			phases.values().forEach(LifecycleGroup::start);
		}
	}

这个地方暂时也不需要太关心,我们先抓重点


publishEvent(new ContextRefreshedEvent(this))

先来看一下需要发布的事件ContextRefreshedEvent

代码语言:javascript
复制
public class ContextRefreshedEvent extends ApplicationContextEvent {

	public ContextRefreshedEvent(ApplicationContext source) {
		super(source);
	}

}

将给定事件发布给所有监听器。

注意:监听器在 MessageSource 之后被初始化,以便能够在监听器实现中访问它。因此,MessageSource 实现不能发布事件。

代码语言:javascript
复制
	@Override
	public void publishEvent(ApplicationEvent event) {
		publishEvent(event, null);
	}

代码语言:javascript
复制
	protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
		Assert.notNull(event, "Event must not be null");

		// Decorate event as an ApplicationEvent if necessary
		ApplicationEvent applicationEvent;
		if (event instanceof ApplicationEvent) {
			applicationEvent = (ApplicationEvent) event;
		}
		else {
			applicationEvent = new PayloadApplicationEvent<>(this, event);
			if (eventType == null) {
				eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
			}
		}

		// Multicast right now if possible - or lazily once the multicaster is initialized
		if (this.earlyApplicationEvents != null) {
			this.earlyApplicationEvents.add(applicationEvent);
		}
		else {
		//发布事件---multicastEvent如何工作的上面已经介绍过了
			getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
		}

		// Publish event via parent context as well...
		//如果指定了父容器---还会向父容器中注册的监听器发布事件
		if (this.parent != null) {
			if (this.parent instanceof AbstractApplicationContext) {
				((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
			}
			else {
				this.parent.publishEvent(event);
			}
		}
	}

小结

到此refresh流程就讲解完毕了,大家可以再从头看一遍该函数的实现,自己回想一下每个步骤做了哪些事情:

代码语言:javascript
复制
	@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.
			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();
			}
		}
	}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring读源码系列08----容器扩展功能--下
  • 注册BeanPostProcessor
    • registerBeanPostProcessors
      • PostProcessorRegistrationDelegate#registerBeanPostProcessors
  • 初始化消息资源
    • initMessageSource
      • MessageSource在哪里被使用呢?
  • 初始化ApplicationEventMulticaster
    • 使用场景演示
      • initApplicationEventMulticaster
        • SimpleApplicationEventMulticaster内部如何派发事件的
        • 空实现onRefresh
        • 注册监听器
          • registerListeners
          • 初始化非延迟加载单例
            • finishBeanFactoryInitialization
              • freezeConfiguration
              • preInstantiateSingletons
          • finishRefresh
            • initLifecycleProcessor
              • getLifecycleProcessor().onRefresh()
                • publishEvent(new ContextRefreshedEvent(this))
                • 小结
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档