Spring - 手把手分析 IoC 容器创建过程

news2024/11/19 3:47:03

概述

这里我们以 Spring 5.2.8.RELEASE 版本为例,看一下 IoC 容器 的创建过程。同时我们使用 java-based 的方式实例化 IoC 容器,即使用 AnnotationConfigApplicationContext + @Configuration 的方式配置容器需要的组件。

ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

查看 AnnotationConfigApplicationContext 的继承关系,可以看到这个继承关系还是很复杂的,其中重要的接口有 BeanFactoryApplicationContextResourceLoaderBeanDefinitionRegistryAnntationConfigRegistry 等:

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
	...
}

在这里插入图片描述

查看创建 IoC 容器 所使用的 AnnotationConfigApplicationContext 的构造函数:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
	// 1、初始化 IoC 容器和一些底层 Bean
	this();
	// 2、注册配置类到容器中
	register(componentClasses);
	// 3、核心流程
	refresh();
}

1、首先查看 this() 方法,即无参构造:

这里有一个细节就是如果你了解 Java类初始化顺序实例初始化顺序 的话,你会知道这里首先会初始化父类,不明白的可以先看一下Java - 详细分析 【类初始化】 和 【实例初始化】 的过程及顺序 这篇文章

首先执行父类 GenericApplicationContext 的初始化方法:

public GenericApplicationContext() {
	// 初始化了 BeanFactory
	this.beanFactory = new DefaultListableBeanFactory();
}

接着执行了自己的初始化方法:

再一次感叹 Spring 的命名,用词很准确、很严谨,基本上都可以做到见名知意,我们在开发中的命名也要尽量做到见名知意

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

	private final AnnotatedBeanDefinitionReader reader;

	private final ClassPathBeanDefinitionScanner scanner;

	public AnnotationConfigApplicationContext() {
		// 1、注解形式的 BeanDefinition 读取器,用来识别 @Autowired、@Resource 等注解
		this.reader = new AnnotatedBeanDefinitionReader(this);
		// 2、用来扫描类路径下的 BeanDefinition
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
	
	...
}

1.1、查看 AnnotatedBeanDefinitionReader 的构造函数:

// 这里的 registry 是 AnnotationConfigApplicationContext
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
	this(registry, getOrCreateEnvironment(registry));
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	Assert.notNull(environment, "Environment must not be null");
	this.registry = registry;
	this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
	// 核心流程
	AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

接着查看 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry) 源码:

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
	// 首先获取到 DefaultListableBeanFactory,其实就是 IoC 容器
	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
	...

	// 这里初始化一些底层的 BeanDefinition,比如处理 @Autowired、@Resource 注解的底层 Bean
	// 默认会初始化 5 个
	//org.springframework.context.annotation.internalConfigurationAnnotationProcessor
	//org.springframework.context.annotation.internalAutowiredAnnotationProcessor
	//org.springframework.context.annotation.internalCommonAnnotationProcessor
	//org.springframework.context.event.internalEventListenerProcessor
	//org.springframework.context.event.internalEventListenerFactory
	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

	...

	return beanDefs;
}

1.2、查看 ClassPathBeanDefinitionScanner 的构造函数

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
	this(registry, true);
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {

	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	this.registry = registry;

	if (useDefaultFilters) {
		// 1、注册默认的过滤器
		registerDefaultFilters();
	}
	// 2、设置 environment
	setEnvironment(environment);
	// 3、初始化 resourceLoader
	setResourceLoader(resourceLoader);
}

1.2.1、查看 registerDefaultFilters() 方法,主要是为了过滤 @Component@ManagedBean@Named 注解:

protected void registerDefaultFilters() {
	this.includeFilters.add(new AnnotationTypeFilter(Component.class));
	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
		...
	try {
		this.includeFilters.add(new AnnotationTypeFilter(
				((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
	...
}

1.2.2、设置 environment 信息

// 这里的 BeanDefinitionRegistry 为 AnnotationConfigApplicationContext
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
	// 从最上面的 AnnotationConfigApplicationContext 类图中可以看到这里为 true
	if (registry instanceof EnvironmentCapable) {
		// 这里会进入到 AnnotationConfigApplicationContext 的父类 AbstractApplicationContext 中的实现方法
		return ((EnvironmentCapable) registry).getEnvironment();
	}
	return new StandardEnvironment();
}
// AbstractApplicationContext

@Override
public ConfigurableEnvironment getEnvironment() {
	if (this.environment == null) {
		this.environment = createEnvironment();
	}
	return this.environment;
}

protected ConfigurableEnvironment createEnvironment() {
	return new StandardEnvironment();
}

2、查看 register(componentClasses),注册配置类信息

由此可知,配置类也会作为一个 Bean 被注册到容器中

@Override
public void register(Class<?>... componentClasses) {
	Assert.notEmpty(componentClasses, "At least one component class must be specified");
	// 这里的 reader 就是上一步初始化的 AnnotatedBeanDefinitionReader
	this.reader.register(componentClasses);
}

// 重载方法
public void registerBean(Class<?> beanClass) {
	doRegisterBean(beanClass, null, null, null, null);
}

查看 AnnotatedBeanDefinitionReaderregister 方法:

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	abd.setInstanceSupplier(supplier);
	// 处理 Bean 上面是否有 @Scope 注解
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

	// 处理其他注解,比如 @Lazy、@Primary、@DependsOn 等
	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
	...

	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	// 注册 BeanDefinition
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

查看 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry) 方法:

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

	// Register bean definition under primary name.
	String beanName = definitionHolder.getBeanName();
	// 注册 BeanDefinition 到 BeanFactory
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

	// Register aliases for bean name, if any.
	String[] aliases = definitionHolder.getAliases();
	if (aliases != null) {
		for (String alias : aliases) {
			registry.registerAlias(beanName, alias);
		}
	}
}

这里使用的 registerBeanDefinition 方法是在 GenericApplicationContext 中重写的方法:

@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {
	// 这个 beanFacory 就是 this() 方法中初始化的 DefaultListableBeanFactory
	this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}

3、接下来就是最重要的 refresh() 方法

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 1、做一些 refresh 前的准备工作
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 2、让子类刷新内部 Bean 工厂
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 3、BeanFactory 的一些准备工作,上一步并没有做太多,只是获取到了 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、执行 BeanFactoryProcessor
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 6、注册 BeanPostProcessor
			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、添加一些额外的 refresh 工作
			onRefresh();

			// Check for listener beans and register them.
			// 10、注册监听器
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// 11、完成 BeanFactory 的初始化
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// 12、完成 refresh 方法
			finishRefresh();
		}

		catch (BeansException ex) {
			...
		}

		finally {
			// Reset common introspection caches in Spring's core, since we
			// might not ever need metadata for singleton beans anymore...
			resetCommonCaches();
		}
	}
}

3.1、prepareRefresh() 刷新前的准备工作

protected void prepareRefresh() {
	// Switch to active.
	// 记录 Ioc 容器初始化开始时间戳,并设置当前状态是 close 还是 active
	this.startupDate = System.currentTimeMillis();
	this.closed.set(false);
	this.active.set(true);

	...

	// Initialize any placeholder property sources in the context environment.
	// 由子类实现,加载 PropertySource 到 context 环境中
	initPropertySources();

	// Validate that all properties marked as required are resolvable:
	// see ConfigurablePropertyResolver#setRequiredProperties
	// 校验属性是否合法等
	getEnvironment().validateRequiredProperties();

	// 保存一些 refresh 之前的 Listener 和 Event
	...
}

3.2、obtainFreshBeanFactory() 刷新并返回 BeanFactory

这两个方法都是抽象方法,又因为 AnnotationConfigApplicationContext 继承了 GenericApplicationContext,所以调用的是 GenericApplicationContext 中的 refreshBeanFactory 方法

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	// 核心流程,刷新 BeanFactory
	refreshBeanFactory();
	// 返回刷新后的 BeanFactory
	return getBeanFactory();
}

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

@Override
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

查看 GenericApplicationContext 中的实现:

@Override
protected final void refreshBeanFactory() throws IllegalStateException {
	if (!this.refreshed.compareAndSet(false, true)) {
		throw new IllegalStateException(
				"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
	}
	// 只是设置了一下 serializationId
	this.beanFactory.setSerializationId(getId());
}

getBeanFactory() 方法返回的是第 1 步中初始化的 DefaultListableBeanFactory

3.3、prepareBeanFactory(beanFactory) 进行一些属性设置

设置了很多属性,但是这里与主流程无关,就没有详细说明每一项属性的含义,感兴趣的可以查看官方文档。其实代码中的注释已经说的很清楚了,Spring 的撰写文档能力毋庸置疑,英语要学好啊。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	// 设置类加载器
	beanFactory.setBeanClassLoader(getClassLoader());
	// 表达式解析器
	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));
	// 忽略各种 Aware
	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.
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	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.
	// 注册了一些默认的 bean
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

3.4、postProcessBeanFactory(beanFactory)

BeanFactory 准备工作完成后进行的后置处理工作,由子类重写这个方法来自定义具体的逻辑

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

以上步骤主要完成了 BeanFactory 的创建以及预准备工作


3.5、invokeBeanFactoryPostProcessors(beanFactory)

执行 BeanFactoryPostProcessor,执行时机是在 BeanFactory 的标准初始化之后,所有的 BeanDefinition 已经被加载,但是还没有 Bean 被初始化。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// 核心流程
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

BeanFactoryPostProcessor 有一个子类 BeanDefinitionRegistryPostProcessor,在 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 方法中,优先执行实现了 BeanDefinitionRegistryPostProcessor 的实现类,再执行实现了 BeanFactoryPostProcessor 的实现类,在 Spring - IoC 容器之拓展点 BeanFactoryPostProcessor 这篇文章中,有分析过,这里就不再赘述了。

3.6、registerBeanPostProcessors(beanFactory)

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);

	// 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;
	beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

	// 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<>();
	...

	// First, register the BeanPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

	// Next, register the BeanPostProcessors that implement Ordered.
	List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	...
	sortPostProcessors(orderedPostProcessors, beanFactory);
	registerBeanPostProcessors(beanFactory, orderedPostProcessors);

	// Now, register all regular BeanPostProcessors.
	List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	...
	registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

	// Finally, re-register all internal BeanPostProcessors.
	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).
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

首先获取到实现了 PriorityOrderedBeanPostProcessor 并注册到 BeanFactory 中,其次获取实现了 Ordered 接口的并注册,之后注册没有排序规则的,最后注册实现了 MergedBeanDefinitionPostProcessor 接口的。

3.7、initMessageSource()

用来做国际化、消息处理、消息解析等功能,SpringMVC 中再详细分析这一块的源码

3.8、initApplicationEventMulticaster()

protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		...
	}
	else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		// 将 applicationEventMulticaster 添加到 IoC 容器中,以便其他组件可以引用
		beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		...
	}
}

3.9、onRefresh()

由子类实现自定义的逻辑,是为了添加一些特殊的 refresh 工作,比如:初始化一些特殊的 Bean

protected void onRefresh() throws BeansException {
	// For subclasses: do nothing by default.
}

3.10、registerListeners()

注册实现了 ApplicationListener 的监听器

protected void registerListeners() {
	// Register statically specified listeners first.
	for (ApplicationListener<?> listener : getApplicationListeners()) {
		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);
		}
	}
}

3.11、【重要】finishBeanFactoryInitialization(beanFactory)

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 非核心流程这里就省略了
	...

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

在前面的流程中,有一些 Bean 已经被初始化,这里的 preInstantiateSingletons() 是用来初始化剩下的单实例 Bean,这里的 getBean(beanName) 就是创建 Bean 的过程,由于篇幅过长这里就不分析了,在 Spring - 分析 IoC 容器中 Bean 的创建过程 这篇文章中详细分析。

@Override
public void preInstantiateSingletons() throws BeansException {
	...

	// 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.
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					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 {
				// 核心流程
				getBean(beanName);
			}
		}
	}

	// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
					smartSingleton.afterSingletonsInstantiated();
					return null;
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

3.12、finishRefresh()

完成 IoC 容器 创建的收尾工作

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.
	getLifecycleProcessor().onRefresh();

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

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

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

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

相关文章

【云IDE初体验】与君相逢恨晚,真正的轻量级开发工具

云IDE产品介绍 云IDE使用教程 免费使用地址&#xff1a;点击【云IDE】&#xff0c;即可开始创建工作空间啦~ 云IDE1.云IDE介绍2. 使用流程3. 体验总结作为一名大学生&#xff0c;学习的地点很关键&#xff0c;尤其是我们计算机系&#xff0c;更是离不开电脑&#xff0c;去图书馆…

调度线程池 ScheduledThreadPoolExecutor 的正确使用姿势

前言 项目中经常会遇到一些非分布式的调度任务&#xff0c;需要在未来的某个时刻周期性执行。实现这样的功能&#xff0c;我们有多种方式可以选择&#xff1a; Timer类&#xff0c; jdk1.3 引入&#xff0c;不推荐 它所有任务都是串行执行的&#xff0c;同一时间只能有一个任…

【C语言】移位操作符 位操作符 - 对二进制位进行精准操作【+面试题目】_[初阶篇]

快速导航 【前言】 1.移位操作符 1.1左移操作符(<<) 1.2右移操作符(>>) 2.位操作符 2.1 & 按位与 2.2 | (按位或) 2.3 ^ (按位异或) 3.面试题目 3.1 交换两个变量&#xff08;不创建临时变量&#xff09; 3.2统计二进制中1的个数 3.2.1 方法一&#xff1a;…

复合事件归因分析

1 复合事件 1.1 概述 1.2 类型 1.2.1 先决条件事件&#xff08;preconditioned events&#xff09; 1.2.2 多变量事件&#xff08;multivariate CEs&#xff09; eg.高温干旱 1.2.3 时间复合事件&#xff08;temporally CEs&#xff09; eg.旱涝急转 1.2.4 空间复合事件…

电子电路设计基本概念100问(二)【学习目标:原理图、PCB、阻抗设计、电子设计基本原则、基本原器件等】

笔者电子信息专业硕士毕业&#xff0c;获得过多次电子设计大赛、大学生智能车、数学建模国奖&#xff0c;现就职于南京某半导体芯片公司&#xff0c;从事硬件研发&#xff0c;电路设计研究。对于学电子的小伙伴&#xff0c;深知入门的不易&#xff0c;特开次博客交流分享经验&a…

【每天学习一点新知识】网络安全--拒绝服务攻击

目录 1、SYN泛洪攻击 SYN泛洪攻击原理 攻击过程 防御机制 2、Smurf攻击 Smurf攻击原理 间接攻击 放大攻击 防御机制 3、DDoS DDoS原理 直接DDoS攻击 间接DDoS攻击 防御机制 1、SYN泛洪攻击 SYN泛洪攻击原理 终端访问Web服务器之前需要和服务器之间建立TCP连接。W…

万字长文解析Scaled YOLOv4模型(YOLO变体模型)

一&#xff0c;Scaled YOLOv4 摘要1&#xff0c;介绍2&#xff0c;相关工作 2.1&#xff0c;模型缩放 3&#xff0c;模型缩放原则 3.1&#xff0c;模型缩放的常规原则3.2&#xff0c;为低端设备缩放的tiny模型3.3&#xff0c;为高端设备缩放的Large模型 4&#xff0c;Scaled-YO…

大学毕业后,我就送了2个月外卖,哭了一整晚

先简单介绍一下自己&#xff0c;我来自湛江&#xff0c;大学学的的物流管理专业&#xff0c;现在就职于一家互联网公司&#xff0c;从事软件测试工作。 我来自湛江的一个偏远农村&#xff0c;家里兄弟姐妹多&#xff0c;父母无力负担我的学费&#xff0c;很多时候学费都是靠姐…

红黑树 - c++

文章目录&#xff1a;红黑树的介绍红黑树节点定义红黑树的插入操作红黑树的删除红黑树的验证红黑树 vs AVL树红黑树的介绍 红黑树(Red-Black-Tree)&#xff0c;通常写为 R-B Tree。它是一种特殊的二叉搜索树。红黑树的每个节点上都有一个存储位来标识节点的颜色&#xff0c;可…

积木报表—JimuReport v1.5.4版本发布,免费的可视化Web报表工具

项目介绍 一款免费的低代码可视化报表&#xff0c;像搭建积木一样在线拖拽设计&#xff01;低代码开发必备&#xff0c;功能涵盖&#xff0c;数据报表、打印设计、图表报表、大屏设计等&#xff01; 秉承“简单、易用、专业”的产品理念&#xff0c;极大的降低报表开发难度、缩…

【css伪类选择器及透明度——附项目图片及代码】

不知不觉&#xff0c;又鸽了好长时间了&#xff0c;非常抱歉&#xff0c;没办法&#xff0c;毕竟开学了&#xff0c;今天课少&#xff0c;抽出了两个小时写了一篇css的&#xff0c;每天不是被催更&#xff0c;就是在催更的路上。放心&#xff0c;小陈陈有时间一定会给大家分享好…

SVM 支持向量机

SVM 支持向量机SVM 原理最优化问题线性不可分sklearn 调用 SVM核函数SVM 原理 前置知识&#xff1a;用迭代策略来划分样本&#xff0c;请猛击《神经元的计算》。 SVM 也是用一条迭代的直线来划分不同数据之间的边界&#xff1a; .- 是一条直线&#xff08;线性函数&#xff09…

数据结构c语言版第二版(严蔚敏)第五章笔记

目录 树和二叉树的定义 树的定义 树的基本术语 二叉树的定义 二叉树的性质和存储结构 二叉树的性质 二叉树的存储结构 顺序存储结构 链式存储结构 遍历二叉树和线索二叉树 遍历二叉树 先序遍历 中序遍历 后序遍历 前序遍历的递归算法 中序遍历的递归算法 后序…

SARScape中用sentinel-1数据做SBAS-InSAR完整流程(2/2)

书接上回&#xff1a;SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;1/2&#xff09; SARScape中用sentinel-1数据做SBAS-InSAR完整流程&#xff08;2/2&#xff09;7 反演第一步Inversion&#xff1a;First Step7.1 导入设置7.2 optional file7.3 parameters参数…

齐博x1用户登录接口

用户的登录主要涉及到小程序登录、APP的帐号密码登录、APP的微信开发平台帐号登录。 相应的地址是&#xff1a;http://qb.net/index.php/index/wxapp.login/index.html 涉及到的方法如下 上面的地址&#xff0c;默认是小程序的登录与注册。 http://qb.net/index.php/index/wxa…

matlab/simulink电力电子仿真傅里叶变换模块(fourier)测幅值相角的设置与使用

matlab/simulink电力电子仿真傅里叶变换模块&#xff08;fourier&#xff09;测幅值相角的设置与使用 今天要说的是一个可以测量信号的幅值和相角的模块&#xff0c;fourier&#xff0c;长下面这样&#xff1a; 有时候我们需要求某个信号的幅值或者相位&#xff0c;或求两个…

用文字描述给黑白照上色,这个免费网站火了!网友:比其他同类都好用

金磊 Alex 发自 凹非寺量子位 | 公众号 QbitAI这是清朝末代皇后婉容广为流传的一张老照片&#xff1a;如果让照片变成彩色的&#xff0c;会是什么样子&#xff1f;竟然没有什么违和感&#xff0c;百年前的老照片似乎在此刻变得鲜活了起来。而这张图上色的背后&#xff0c;并没有…

BUUCTF NewStarCTF 公开赛赛道Week5 Writeup

文章目录WEBGive me your photo PLZBabySSTI_ThreeUnsafe ApacheSo Baby RCE AgainFinal roundMISC最后的流量分析奇怪的PDF 2奇怪的文本Yesec no drumsticks 5qsdzs girlfriend 5WEB Give me your photo PLZ 可上传.htaccess AddType application/x-httpd-php .jpg然后上传…

干货!手把手教你穿透内网

干货&#xff01;手把手教你穿透内网干货&#xff01;手把手教你穿透内网cpolar内网穿透使用场景如何使用cpolar内网穿透&#xff1f; ↓↓1. 注册cpolar账号2. 安装cpolar内网穿透2.1 Windows系统2.2 Linux系统2.2.1 安装2.2.2 向系统添加服务2.2.3 启动服务2.2.4 查看服务状态…

生成二维码或条形码JavaScript脚本库

二维码或条形码在日常生活中现在应用已经非常普遍了&#xff0c;文章分享生成条形码和二维码的JavaScript库。 条形码 条形码是日常生活中比较常见的&#xff0c;主要用于商品。通俗的理解就是一串字符串的集合&#xff08;含字母、数字及其它ASCII字符的集合应用&#xff09…