当前位置: 首页 > article >正文

Spring(三)ApplicationContext刷新全过程

ApplicationContext作为beanFactory的门面,他集成了beanFactory的能力并进行了扩展。

其内部有一个核心方法refresh,下面简单描述一下refresh各个方法的内容

refresh方法简介

org.springframework.context.support.AbstractApplicationContext#refresh

            // 准备刷新获取bean工厂的前置操作,其内部可以扩展为添加资源,以及进行资源的校验
            // 重要程度 低
            prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
            // 这个就是一个很重要的方法,其内部会生成一个beanFactory,然后加载bean定义
            // 不过不涉及到扩展点方面
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
            // 像bean工厂中自动注册一些实例。
            // 比如 ApplicationContextAwareProcessor,他利用了beanPostProcessor机制。完成了ApplicationContextAware的实现,并且注册了envorinment、systemProperties属性
			prepareBeanFactory(beanFactory);

        
            // 这是一个空方法,也就是模版方法,等待子类覆盖,对beanFactory进行改造
            postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
            // 这个方法是用来加载beanFactory的processor的,很重要,后面描述
			invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
            // 注册beanPostProcessor,也很重要
			registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
            // 国际化消息这一块,用到看下就行
			initMessageSource();

				// Initialize event multicaster for this context.
            // spring利用监听者模式搞了个消息的监听和广播,用到看下就行
			initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
            // 模版方法,空的
			onRefresh();

				// Check for listener beans and register them.
            // 这还是spring的广播消息的内容,属于注册监听者这一块的
			registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
            // 内部有两个内容很重要 1、冻结bean定义的更改 2、加载单例bean
			finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
            // 加载完成了,当然要发个广播消息了。另外还搞了个spring的声明周期,此处会调用周期的onRefresh方法。
			finishRefresh();

refresh内部方法抽要介绍

prepareBeanFactory方法

其内部有一个我认为比较重要的方法,和applicationContext的aware扩展点有关,具体调用如下。

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

其ApplicationContextAwareProcessor实现了BeanPostProcessor接口,并重写了postProcessBeforeInitialization方法

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
		AccessControlContext acc = null;

		if (System.getSecurityManager() != null &&
				(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
						bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
						bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					invokeAwareInterfaces(bean);
					return null;
				}
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

	private void invokeAwareInterfaces(Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof EnvironmentAware) {
				((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
			}
			if (bean instanceof EmbeddedValueResolverAware) {
				((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
			}
			if (bean instanceof ResourceLoaderAware) {
				((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
			}
			if (bean instanceof ApplicationEventPublisherAware) {
				((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
			}
			if (bean instanceof MessageSourceAware) {
				((MessageSourceAware) bean).setMessageSource(this.applicationContext);
			}
			if (bean instanceof ApplicationContextAware) {
				((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
			}
		}
	}

据之前介绍的beanPostProcessor机制介绍,在完成实例化之后,初始化之前会调用postProcessBeforeInitialization方法,此时就判断该bean如果实现了对应的aware接口,则会把对应的内容传递进去。

invokeBeanFactoryPostProcessors方法

这个地方也是ApplicationContext提供的一个核心扩展点,针对BeanDefinitionRegistryPostProcessor以及BeanFactoryPostProcessor。其内部关于两个扩展点的实现基本一致,下面简单的看下是如何按优先级加载BeanFactoryPostProcessor以及调用的

// 1、获取所有的BeanFactoryPostProcessor
String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// 预先准备好三类bean,高优先级的,优先的,没有优先级的
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        // 编辑所有的BeanFactoryPostProcessor,分类
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			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);
			}
		}

		// 按照优先级进行排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        // 对priorityOrderedPostProcessors进行调用
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        // 获取优先的进行排序调用
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 获取没有优先级的无序调用
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

其内部的逻辑顺序如上述代码备注一样

1、获取所有的BeanFactoryPostProcessor

2、分为三类高优先级的,优先的,无优先级的

3、高优先级(实现PriorityOrdered接口)的排序调用

4、优先的(实现Ordered接口)排序调用

5、无优先级的遍历调用

registerBeanPostProcessors方法

和上述代码基本一致。

1、找到所有的BeanPostProcessor

2、分为三类高优先级的,优先的,无优先级的

3、高优先级(实现PriorityOrdered接口)的注册到BeanPostProcessor集合

4、优先的(实现Ordered接口)注册到BeanPostProcessor集合

5、无优先级的注册到BeanPostProcessor集合


http://www.kler.cn/a/381368.html

相关文章:

  • SQLAlchemy 介绍与实践
  • Windows 部署非安装版Redis
  • C语言 -- qsort的简单使用
  • backtrader下的轮动策略模板,附年化20.6%的策略源码。
  • SpringBoot自动装配过程
  • 集合进阶------泛型(JAVA笔记第三十期)
  • 【GCN】 代码详解 (1) 如何运行【pytorch】可运行版本
  • REst full API
  • 如何在 CentOS 7.9 上安装 Docker
  • cesium实现测面功能
  • Redis完全指南:从基础功能到缓存管理与高可用性设计
  • 【Vue 全家桶】2、Vue 组件化编程
  • linux重启PHP
  • vue2开发 对接后端(go语言)常抛异常情况以及处理方法汇总
  • Oracle视频基础1.3.4练习
  • Hadoop期末复习(完整版)
  • dns欺骗
  • Android 面试题汇总
  • Python 线程学习知识大全
  • 如何在 Spring Boot 中实现多数据源的事务管理?
  • 【分布式】分布式锁设计与Redisson源码解析
  • 跨模态对齐与跨领域学习
  • SpringSecurity的使用
  • 操作系统-文件IO
  • Python笔记之线程库threading
  • 【WebApi】C# webapi 后端接收部分属性