Processo de inicialização do COI (5)

1. Visão geral

Simplificando, o processo de inicialização do contêiner do IOC é refresh()iniciado por um método, o que significa o início oficial do contêiner do IOC. Especificamente, essa inicialização inclui principalmente os três processos de posicionamento, carregamento e registro do BeanDefinition Resource.

2. Descrição do processo de inicialização do COI
  • O primeiro processo é o processo de posicionamento de recursos. Esse posicionamento de recurso refere-se ao posicionamento de recurso de BeanDefinition (por exemplo, as várias configurações XML que geralmente configuramos no projeto Spring são unificadas e abstraídas como recursos de recurso), concluídas pelo ResourceLoader por meio de uma interface de recurso unificada. Use fornece uma interface unificada.
  • O segundo processo é o processo de carregamento do BeanDefinition. O processo de carregamento é representar o Bean definido pelo usuário como a estrutura de dados dentro do contêiner IOC, ou seja, BeanDefinition. Na verdade, o BeanDefinition é a abstração dos objetos POJO no contêiner IOC.Por meio da estrutura de dados definida pelo BeanDefinition, o contêiner IOC pode gerenciar facilmente os objetos POJO, ou seja, os objetos Bean.
  • O terceiro processo é o processo de registro do BeanDefinition no IOC. Esse processo é alcançado principalmente através da interface BeanDefinitionRegistry. O processo de registro é registrar o BeanDefinition analisado durante o processo de carregamento no contêiner IOC. De fato, o IOC injeta internamente o BeanDefinition analisado em um HashMap, e o contêiner do IOC mantém esses dados do BeanDefinition por meio desse HashMap.
3. Análise do código fonte

FileSystemXmlApplicationContext como exemplo, o relacionamento principal de herança é:

Relacionamento de herança principal de FileSystemXmlApplicationContext

O código de exemplo é:
FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:bean.xml")

Quando executamos a linha de código acima, o processo de posicionamento, análise e registro de recursos de um COI é concluído.Vamos analisar o fluxo de execução principal do código acima.

/**
	 * Create a new FileSystemXmlApplicationContext, loading the definitions
	 * from the given XML file and automatically refreshing the context.
	 * @param configLocation file path
	 * @throws BeansException if context creation failed
	 */
	public FileSystemXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

O construtor que escolhemos é transmitir um caminho de arquivo de recurso, e o construtor interno realmente chamado é:

/**
	 * Create a new FileSystemXmlApplicationContext with the given parent,
	 * loading the definitions from the given XML files.
	 * @param configLocations array of file paths
	 * @param refresh whether to automatically refresh the context,
	 * loading all bean definitions and creating all singletons.
	 * Alternatively, call refresh manually after further configuring the context.
	 * @param parent the parent context
	 * @throws BeansException if context creation failed
	 * @see #refresh()
	 */
	public FileSystemXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		// 父容器设置
		super(parent);
		// 设置资源访问路径
		setConfigLocations(configLocations);
		// 刷新启动容器
		if (refresh) {
			refresh();
		}
	}

Quando executamos o refresh()método, nosso container de contexto avançado ApplicationContext foi criado, entramos na refresh()área do método para visualizar a lógica de execução específica:

@Override
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 刷新启动前的准备工作
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// 获取Beanfatory->资源的定位和解析就是在此方法中执行的
		//(1)AbstractApplicationContext#obtainFreshBeanFactory()
		//(2)AbstractApplicationContext#refreshBeanFactory()实际执行子类
		//(3)AbstractRefreshableApplicationContext#refreshBeanFactory()的方法
		创建DefaultListableBeanFactory并loadBeanDefinitions`
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// 配置BeanFactory标准Context特征,比如 classloader,后置处理等。
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			// 允许添加BeanFactoryProcessor来修改beanFactory,子类覆盖方法做额外处理  
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// 回调 上面收集到的所有的 BeanFactoryProcessor 了
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			// 注册bean的处理器
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// 国际化相关的初始化
			initMessageSource();

			// Initialize event multicaster for this context.
			// 初始化应用事件的广播
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			// 留给子类Context实现一些特殊处理的模板方法(模板方法留给子类实现)
			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();
		}
	}
}

Conta pública WeChat

Publicado 41 artigos originais · Gostei 14 · Visitantes 10.000+

Acho que você gosta

Origin blog.csdn.net/Yunwei_Zheng/article/details/105680488
Recomendado
Clasificación