Процесс запуска контейнера Spring (интерпретация исходного кода)

Java Spring
Процесс запуска контейнера Spring (интерпретация исходного кода)

Есть чувства, есть галантерейные товары, поиск в WeChat【Третий принц Ао Бин] Обратите внимание на этого другого программиста.

эта статьяGitHub github.com/JavaFamilyВключено, и есть полные тестовые площадки, материалы и мой цикл статей для интервью с производителями первой линии.

предисловие

Spring Framework является одним из самых далеко идущих фреймворков на языке Java.Программисты всегда говорили о двух классических идеях IOC и AOP.Представленные позже серии Spring Boot и Spring Cloud также разработаны на его основе. Чтобы понять серию Spring Family Bucket, вы должны изучить Spring Framework приземленно.

Эта статья является первой из серии анализа исходного кода Spring Framework. В ней в основном анализируется запуск Spring Framework с уровня кода. Идеи здесь синтезированы автором на основе собственного опыта использования Spring и понимания Spring. следующее содержание представляет мое личное мнение, если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь, дайте мне знать.

Напоминаем, что эта статья основана на анализе кода версии 5.1.6.RELEASE, и код входа также использует официально рекомендованную технологию java-config вместо xml.

Анализ исходного кода

Учитывая, что смотреть исходный код напрямую — очень скучный процесс, а дизайн кода Spring очень хорош и стандартизирован, это приведет к частым скачкам между классами при листании исходного кода, и незнакомые ученики могут прямо запутаться. подготовит блок-схему перед каждым важным процессом.Рекомендуется сначала понять общие шаги по блок-схеме, а затем жестко запрограммировать код, что может значительно снизить сложность.

Я считаю, что каждый студент, который использовал технологию Spring, знает, что у Spring есть очень важный шаг в процессе инициализации, то есть обновление контейнера Spring.Этот шаг важен, но процесс инициализации перед обновлением также очень важен. В этой статье весь процесс запуска разделен на две части: инициализация и обновление контейнера.Ниже приведен официальный запуск.

процесс инициализации

Анализ процесса

Поскольку исходный код анализируется на основе технологии java-config, запись здесьAnnotationConfigApplicationContext, если используется анализ xml, то записьClassPathXmlApplicationContextОбщая особенность обоих из них состоит в том, что они оба наследуютAbstractApplicationContextКласс, а знаменитыйrefreshМетод определен в этом классе, так что не буду сейчас его спойлерить, давайте его разберемAnnotationConfigApplicationContextкласс, который можно изобразить в виде следующей блок-схемы:

Прочитав блок-схему, мы должны подумать об этом: если бы вас попросили спроектировать контейнер IOC, что бы вы сделали? Сначала обязательно предоставлю запись(AnnotationConfigApplicationContext) для использования пользователями, а затем необходимо инициализировать ряд компонентов инструмента:

①: Если я хочу генерировать объекты bean-компонентов, мне нужна фабрика beanFactory (DefaultListableBeanFactory);

②: Если я хочу добавить конкретную аннотацию (например,@Service,@Repository) класс для чтенияBeanDefinitionобъект (BeanDefinitionЭто чрезвычайно важная концепция в Spring, которая хранит всю характерную информацию об объекте bean-компонента, например, является ли он синглтоном, загружается ли он отложенно, factoryBeanName и т. д.), тогда требуется считыватель конфигурации аннотаций (AnnotatedBeanDefinitionReader);

③: Если я хочу сканировать указанный пользователем каталог пакетов, чтобы найти объекты bean-компонентов, мне также нужен сканер путей (ClassPathBeanDefinitionScanner).

Благодаря вышеизложенному мышлению, легко ли понять приведенную выше картину?

ps: На желтые ремарки на рисунке можно не обращать внимания, но здесь наглядно показано, когда и где некоторые встроенные компоненты Spring добавляются в контейнер Роль компонентов будет подробно разобрана в следующей серии статей.

Анализ основного кода

Учитывая, что если разобрать все коды, длина статьи будет слишком большой, поэтому здесь анализируется только основное содержание на уровне исходного кода. как более важные шаги будут подробно проанализированы ниже.

org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors

Согласно анализу приведенного выше рисунка, когда здесь запускается код, контейнер Spring построен, то вы можете добавить в контейнер некоторые встроенные компоненты, наиболее важными из которых являютсяConfigurationClassPostProcessorиAutowiredAnnotationBeanPostProcessor, первый — постпроцессор beanFactory, используемый для завершения сканирования и внедрения bean-компонентов, второй — постпроцессор bean-компонентов, используемый для завершения@AutoWiredАвтоматический впрыск.

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

Этот шаг в основном используется для синтаксического анализа класса конфигурации Spring, переданного пользователем, который фактически преобразуется вBeanDefinitionТогда зарегистрируйтесь в контейнере, нечего сказать.

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
		@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
	// 解析传入的配置类,实际上这个方法既可以解析配置类,也可以解析 Spring bean 对象
	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
	// 判断是否需要跳过,判断依据是此类上有没有 @Conditional 注解
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	abd.setInstanceSupplier(instanceSupplier);
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
	// 处理类上的通用注解
	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
	if (qualifiers != null) {
		for (Class<? extends Annotation> qualifier : qualifiers) {
			if (Primary.class == qualifier) {
				abd.setPrimary(true);
			}
			else if (Lazy.class == qualifier) {
				abd.setLazyInit(true);
			}
			else {
				abd.addQualifier(new AutowireCandidateQualifier(qualifier));
			}
		}
	}
	// 封装成一个 BeanDefinitionHolder
	for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
		customizer.customize(abd);
	}
	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	// 处理 scopedProxyMode
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

	// 把 BeanDefinitionHolder 注册到 registry
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

процесс обновления

Анализ процесса

Следующий фрагмент кода — самый важный шаг в Spring: обновление контейнера, также посмотрите на картинку, а затем проанализируйте ее.

После прочтения блок-схемы давайте сначала подумаем об этом: в 3.1 мы знаем, как инициализировать контейнер IOC, затем следующим шагом будет заставить контейнер IOC действительно работать: то есть сначала отсканировать bean-компоненты, которые нужно поместить в контейнер. , упакуйте какBeanDefinitionObject, затем создайте bean-компонент путем отражения и выполните операции присваивания, это самая простая функция контейнера IOC. Но после прочтения картинки процесс инициализации очевидного Spring представляет собой нечто большее, и мы подробно разберем замысел этого дизайна:

Если пользователь хочет выполнить некоторые пользовательские операции после сканирования bean-компонентов: предполагая, что контейнер содержит a и b, затем динамически внедрить c в контейнер, если не удовлетворяет, внедрить d, этот тип операции также поддерживается Spring, извлекая выгоду из это обеспечиваетBeanFactoryPostProcessorПостпроцессор, соответствующий приведенному выше рисункуinvokeBeanFactoryPostProcessorsработать.

Что, если пользователь все еще хочет что-то сделать до и после инициализации бина? Например, создание прокси-объектов, изменение свойств объекта и т. д. Spring предоставляет намBeanPostProcessorПостпроцессор, на самом деле большинство функций в контейнере Spring выполняются через постпроцессор Bean, и Spring также предоставляет нам точку входа, которая соответствует той, что на рисунке выше.registerBeanPostProcessorsработать.

В течение всего процесса создания контейнера, если пользователь хочет отслеживать такие события, как запуск и обновление контейнера, и выполнять некоторые пользовательские операции на основе этих событий? Spring уже рассмотрел это за нас и предоставляет интерфейс для добавления слушателей и интерфейс уведомления о событиях контейнера, который соответствует тому, что на рисунке выше.registerListenersработать.

На данный момент, если вы посмотрите на картинку выше, вы думаете, что это намного проще?Давайте проанализируем некоторые важные коды.

Анализ основного кода

org.springframework.context.support.AbstractApplicationContext#refresh

Этот метод является реализацией конкретного кода на рисунке выше, который можно разделить на 12 шагов, наиболее важные из которых будут подробно описаны ниже.

Здесь нам нужно помнить: каждый контейнер в Spring будет вызывать метод обновления для обновления, будь то контейнер родитель-потомок Spring или фиктивный изолированный контейнер в Spring Cloud Feign, каждый контейнер будет вызывать этот метод для завершения инициализации.

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 1. 刷新前的预处理
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 3. 预处理 beanFactory,向容器中添加一些组件
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 6. 注册 BeanPostProcessors,bean 后置处理器
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)
			initMessageSource();

			// Initialize event multicaster for this context.
			// 8. 初始化事件派发器,在注册监听器时会用到
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用
			onRefresh();

			// Check for listener beans and register them.
			// 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 11. 初始化所有的非单实例 bean
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 12. 发布容器刷新完成事件
			finishRefresh();
		}

		...
		
	}
}

org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

Как следует из названия, этот интерфейс предназначен для добавления некоторых встроенных компонентов в фабрику beanFactory, процесс предварительной обработки.

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	// 设置 classLoader
	beanFactory.setBeanClassLoader(getClassLoader());
	//设置 bean 表达式解析器
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	// 添加一个 BeanPostProcessor【ApplicationContextAwareProcessor】
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

	// 设置忽略自动装配的接口,即不能通过注解自动注入
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
	// 注册可以解析的自动装配类,即可以在任意组件中通过注解自动注入
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Register early post-processor for detecting inner beans as ApplicationListeners.
	// 添加一个 BeanPostProcessor【ApplicationListenerDetector】
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	// 添加编译时的 AspectJ
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// Register default environment beans.
	// 注册 environment 组件,类型是【ConfigurableEnvironment】
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	// 注册 systemProperties 组件,类型是【Map<String, Object>】
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	// 注册 systemEnvironment 组件,类型是【Map<String, Object>】
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

Как мы уже говорили ранее, Spring сканирует все bean-компоненты и преобразует их вBeanDefinitionВ то же время мы можем выполнять некоторые пользовательские операции, благодаря тому, что Spring предоставляет намBeanFactoryPostProcessorинтерфейс.

вBeanFactoryPostProcessorдругой подинтерфейсBeanDefinitionRegistryPostProcessor, первое будетConfigurableListableBeanFactoryподвергаются нашему использованию, что будетBeanDefinitionRegistryРегистратор открыт для нас. После получения регистратора мы можем внедрить его по мере необходимости. Например, для выполнения этого требования: предположим, что контейнер содержит a и b, затем динамически внедрить c в контейнер и внедрить d, если он не устраивает. .

Учащиеся, знакомые со Spring, знают, что компоненты того же типа в Spring позволяют нам управлять порядком, например те, которые мы обычно используем в АОП.@Orderобратите внимание, здесьBeanFactoryPostProcessorКонечно, интерфейс тоже дает порядок, первой должна выполняться реализацияPriorityOrderedКласс реализации интерфейса, а затем к реализацииOrderedКласс реализации интерфейса и, наконец, остальная часть подпрограммы.BeanFactoryPostProcessorсвоего рода.

В этот момент посмотрите на картинку выше. Это так же просто, как пить воду? Он перезвонит первым.postProcessBeanDefinitionRegistry()метод, а затем перезвонитьpostProcessBeanFactory()метод, и, наконец, обратите внимание на порядок.Давайте посмотрим на конкретную реализацию кода.

public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	// beanFactoryPostProcessors 这个参数是指用户通过 AnnotationConfigApplicationContext.addBeanFactoryPostProcessor() 方法手动传入的 BeanFactoryPostProcessor,没有交给 spring 管理
	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	// 代表执行过的 BeanDefinitionRegistryPostProcessor
	Set<String> processedBeans = new HashSet<>();

	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		// 常规后置处理器集合,即实现了 BeanFactoryPostProcessor 接口
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		// 注册后置处理器集合,即实现了 BeanDefinitionRegistryPostProcessor 接口
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
		// 处理自定义的 beanFactoryPostProcessors(指调用 context.addBeanFactoryPostProcessor() 方法),一般这里都没有
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				// 调用 postProcessBeanDefinitionRegistry 方法
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {
				regularPostProcessors.add(postProcessor);
			}
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// Separate between BeanDefinitionRegistryPostProcessors that implement
		// PriorityOrdered, Ordered, and the rest.
		// 定义一个变量 currentRegistryProcessors,表示当前要处理的 BeanFactoryPostProcessors
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
		// 首先,从容器中查找实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 类型,这里只会查找出一个【ConfigurationClassPostProcessor】
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			// 判断是否实现了 PriorityOrdered 接口
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// 添加到 currentRegistryProcessors
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				// 添加到 processedBeans,表示已经处理过这个类了
				processedBeans.add(ppName);
			}
		}
		// 设置排列顺序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		// 添加到 registry 中
		registryProcessors.addAll(currentRegistryProcessors);
		// 执行 [postProcessBeanDefinitionRegistry] 回调方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		// 将 currentRegistryProcessors 变量清空,下面会继续用到
		currentRegistryProcessors.clear();

		// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
		// 接下来,从容器中查找实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessors 类型,这里可能会查找出多个
		// 因为【ConfigurationClassPostProcessor】已经完成了 postProcessBeanDefinitionRegistry() 方法,已经向容器中完成扫描工作,所以容器会有很多个组件
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			// 判断 processedBeans 是否处理过这个类,且是否实现 Ordered 接口
			if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		// 设置排列顺序
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		// 添加到 registry 中
		registryProcessors.addAll(currentRegistryProcessors);
		// 执行 [postProcessBeanDefinitionRegistry] 回调方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		// 将 currentRegistryProcessors 变量清空,下面会继续用到
		currentRegistryProcessors.clear();

		// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
		// 最后,从容器中查找剩余所有常规的 BeanDefinitionRegistryPostProcessors 类型
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			// 根据类型从容器中查找
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				// 判断 processedBeans 是否处理过这个类
				if (!processedBeans.contains(ppName)) {
					// 添加到 currentRegistryProcessors
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					// 添加到 processedBeans,表示已经处理过这个类了
					processedBeans.add(ppName);
					// 将标识设置为 true,继续循环查找,可能随时因为防止下面调用了 invokeBeanDefinitionRegistryPostProcessors() 方法引入新的后置处理器
					reiterate = true;
				}
			}
			// 设置排列顺序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			// 添加到 registry 中
			registryProcessors.addAll(currentRegistryProcessors);
			// 执行 [postProcessBeanDefinitionRegistry] 回调方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			// 将 currentRegistryProcessors 变量清空,因为下一次循环可能会用到
			currentRegistryProcessors.clear();
		}

		// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
		// 现在执行 registryProcessors 的 [postProcessBeanFactory] 回调方法
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		// 执行 regularPostProcessors 的 [postProcessBeanFactory] 回调方法,也包含用户手动调用 addBeanFactoryPostProcessor() 方法添加的 BeanFactoryPostProcessor
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

	else {
		// Invoke factory processors registered with the context instance.
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	// uninitialized to let the bean factory post-processors apply to them!
	// 从容器中查找实现了 BeanFactoryPostProcessor 接口的类
	String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	// 表示实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
	List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 表示实现了 Ordered 接口的 BeanFactoryPostProcessor
	List<String> orderedPostProcessorNames = new ArrayList<>();
	// 表示剩下来的常规的 BeanFactoryPostProcessors
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		// 判断是否已经处理过,因为 postProcessorNames 其实包含了上面步骤处理过的 BeanDefinitionRegistry 类型
		if (processedBeans.contains(ppName)) {
			// skip - already processed in first phase above
		}
		// 判断是否实现了 PriorityOrdered 接口
		else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		}
		// 判断是否实现了 Ordered 接口
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		// 剩下所有常规的
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
	// 先将 priorityOrderedPostProcessors 集合排序
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 执行 priorityOrderedPostProcessors 的 [postProcessBeanFactory] 回调方法
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
	// 接下来,把 orderedPostProcessorNames 转成 orderedPostProcessors 集合
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	// 将 orderedPostProcessors 集合排序
	sortPostProcessors(orderedPostProcessors, beanFactory);
	// 执行 orderedPostProcessors 的 [postProcessBeanFactory] 回调方法
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// Finally, invoke all other BeanFactoryPostProcessors.
	// 最后把 nonOrderedPostProcessorNames 转成 nonOrderedPostProcessors 集合,这里只有一个,myBeanFactoryPostProcessor
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	// 执行 nonOrderedPostProcessors 的 [postProcessBeanFactory] 回调方法
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	// Clear cached merged bean definitions since the post-processors might have
	// modified the original metadata, e.g. replacing placeholders in values...
	// 清除缓存
	beanFactory.clearMetadataCache();
}

org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors

Этот шаг заключается в впрыскивании в контейнерBeanPostProcessor, обратите внимание, что это только вводится в контейнер, а не используется. Обратитесь к приведенным выше шагам и следующему коду, читатель может проанализировать его самостоятельно, это не должно быть очень сложно.

оBeanPostProcessor, его роль будет подробно разобрана в следующей статье о процессе создания Spring bean-компонента, конечно же, невозможно проанализировать всеBeanPostProcessorкомпонент, для написания может потребоваться несколько продолжений, здесь нам просто нужно просто понять, что этот компонент будет мешать процессу инициализации bean-компонента Spring, чтобы выполнять различные функции, такие как прокси, автоматическое внедрение и циклическая зависимость.

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

	// 从容器中获取 BeanPostProcessor 类型
	String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

	// Register BeanPostProcessorChecker that logs an info message when
	// a bean is created during BeanPostProcessor instantiation, i.e. when
	// a bean is not eligible for getting processed by all BeanPostProcessors.
	int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
	// 向容器中添加【BeanPostProcessorChecker】,主要是用来检查是不是有 bean 已经初始化完成了,
	// 如果没有执行所有的 beanPostProcessor(用数量来判断),如果有就会打印一行 info 日志
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// Separate between BeanPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	// 存放实现了 PriorityOrdered 接口的 BeanPostProcessor
	List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 存放 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor
	List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
	// 存放实现了 Ordered 接口的 BeanPostProcessor 的 name
	List<String> orderedPostProcessorNames = new ArrayList<>();
	// 存放剩下来普通的 BeanPostProcessor 的 name
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	// 从 beanFactory 中查找 postProcessorNames 里的 bean,然后放到对应的集合中
	for (String ppName : postProcessorNames) {
		// 判断有无实现 PriorityOrdered 接口
		if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			priorityOrderedPostProcessors.add(pp);
			// 如果实现了 PriorityOrdered 接口,且属于 MergedBeanDefinitionPostProcessor
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				// 把 MergedBeanDefinitionPostProcessor 类型的添加到 internalPostProcessors 集合中
				internalPostProcessors.add(pp);
			}
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	// 给 priorityOrderedPostProcessors 排序
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 先注册实现了 PriorityOrdered 接口的 beanPostProcessor
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	// 从 beanFactory 中查找 orderedPostProcessorNames 里的 bean,然后放到对应的集合中
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
	for (String ppName : orderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		orderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 给 orderedPostProcessors 排序
	sortPostProcessors(orderedPostProcessors, beanFactory);
	// 再注册实现了 Ordered 接口的 beanPostProcessor
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
	for (String ppName : nonOrderedPostProcessorNames) {
		BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
		nonOrderedPostProcessors.add(pp);
		if (pp instanceof MergedBeanDefinitionPostProcessor) {
			internalPostProcessors.add(pp);
		}
	}
	// 再注册常规的 beanPostProcessor
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	// 排序 MergedBeanDefinitionPostProcessor 这种类型的 beanPostProcessor
	sortPostProcessors(internalPostProcessors, beanFactory);
	// 最后注册 MergedBeanDefinitionPostProcessor 类型的 beanPostProcessor
	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】 beanPostProcessor,判断是不是监听器,如果是就把 bean 放到容器中保存起来
	// 此时容器中默认会有 6 个内置的 beanPostProcessor
		// 0 = {ApplicationContextAwareProcessor@1632}
		//	1 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@1633}
		//	2 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@1634}
		//	3 = {CommonAnnotationBeanPostProcessor@1635}
		//	4 = {AutowiredAnnotationBeanPostProcessor@1636}
		//	5 = {ApplicationListenerDetector@1637}
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

org.springframework.context.support.AbstractApplicationContext#initApplicationEventMulticaster

Как мы упоминали ранее, в течение всего процесса создания контейнера Spring будет публиковать множество событий контейнера, таких как запуск контейнера, обновление, завершение работы и т. д. Реализация этой функции выигрывает отApplicationEventMulticasterКомпонент широковещательной рассылки, через который отправляются уведомления о событиях.

Здесь Spring также предоставляет нам расширения,SimpleApplicationEventMulticasterПо умолчанию синхронный. Если мы хотим изменить его на асинхронный, нам нужно только настроить контейнер с именем applicationEventMulticaster в контейнере. Подобные идеи будут больше отражены в последующем Spring Boot, который не будет повторяться здесь.

protected void initApplicationEventMulticaster() {
	// 获取 beanFactory
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	// 看看容器中是否有自定义的 applicationEventMulticaster
	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 {
		// 没有,就创建一个 SimpleApplicationEventMulticaster
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		// 将创建的 ApplicationEventMulticaster 添加到 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() + "]");
		}
	}
}

org.springframework.context.support.AbstractApplicationContext#registerListeners

Если пользователь хочет прослушивать события контейнера, то это должно быть реализовано согласно спецификации.ApplicationListenerинтерфейса и поместите его в контейнер, где он будет просканирован Spring и добавлен вApplicationEventMulticasterВ вещателе уведомления о событиях могут быть опубликованы позже, а соответствующие слушатели получат сообщения для обработки.

protected void registerListeners() {
	// Register statically specified listeners first.
	// 获取之前步骤中保存的 ApplicationListener
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		// getApplicationEventMulticaster() 就是获取之前步骤初始化的 applicationEventMulticaster
		getApplicationEventMulticaster().addApplicationListener(listener);
	}

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	// uninitialized to let post-processors apply to them!
	// 从容器中获取所有的 ApplicationListener
	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...
	// 派发之前步骤产生的 application events
	Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
	this.earlyApplicationEvents = null;
	if (earlyEventsToProcess != null) {
		for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
			getApplicationEventMulticaster().multicastEvent(earlyEvent);
		}
	}
}

org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

На приведенных выше шагах было инициализировано большинство компонентов Spring, а оставшийся шаг — инициализировать все оставшиеся bean-компоненты с одним экземпляром. прокси и т. д., это содержание не будет повторяться здесь. В следующей серии статей будет подробно рассмотрено. Здесь нам нужно только понять, что Spring использует этот метод для инициализации всех bean-компонентов в контейнере.

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.
	// 获取容器中的所有 beanDefinitionName
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	// 循环进行初始化和创建对象
	for (String beanName : beanNames) {
		// 获取 RootBeanDefinition,它表示自己的 BeanDefinition 和可能存在父类的 BeanDefinition 合并后的对象
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 如果是非抽象的,且单实例,非懒加载
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 如果是 factoryBean,利用下面这种方法创建对象
			if (isFactoryBean(beanName)) {
				// 如果是 factoryBean,则 加上 &,先创建工厂 bean
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					final FactoryBean<?> factory = (FactoryBean<?>) bean;
					boolean isEagerInit;
					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) {
						getBean(beanName);
					}
				}
			}
			else {
				// 不是工厂 bean,用这种方法创建对象
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		// 检查所有的 bean 是否是 SmartInitializingSingleton 接口
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				// 回调 afterSingletonsInstantiated() 方法,可以在回调中做一些事情
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

org.springframework.context.support.AbstractApplicationContext#finishRefresh

После инициализации всего контейнера здесь будут выполнены некоторые завершающие работы, такие как очистка кеша, инициализация процессора жизненного цикла, публикация события обновления контейнера и т.д.

protected void finishRefresh() {
	// Clear context-level resource caches (such as ASM metadata from scanning).
	// 清理缓存
	clearResourceCaches();

	// Initialize lifecycle processor for this context.
	// 初始化和生命周期有关的后置处理器
	initLifecycleProcessor();

	// Propagate refresh to lifecycle processor first.
	// 拿到前面定义的生命周期处理器【LifecycleProcessor】回调 onRefresh() 方法
	getLifecycleProcessor().onRefresh();

	// Publish the final event.
	// 发布容器刷新完成事件
	publishEvent(new ContextRefreshedEvent(this));

	// Participate in LiveBeansView MBean, if active.
	LiveBeansView.registerApplicationContext(this);
}

Я Ао Бин,Чем больше вы знаете, тем больше вы не знаете, спасибо за ваши таланты:как,собиратьиКомментарий, увидимся в следующий раз!


Статья постоянно обновляется, вы можете искать в WeChat "Третий принц Ао Бин"Прочтите это в первый раз, ответьте [материал] Подготовленные мной материалы интервью и шаблоны резюме крупных заводов первой линии, эта статьяGitHub github.com/JavaFamilyОн был включен, и есть полные тестовые сайты для интервью с крупными заводами.Добро пожаловать в Star.