Spring iOC主流程初始化方法org.springframework.context.support.AbstractApplicationContext#refresh方法

Spring iOC主流程初始化方法org.springframework.context.support.AbstractApplicationContext#refresh方法

##### 启动测试类

  @Test
    public void  beanTest(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        Result bean = context.getBean(Result.class);

        context.close();
    }
}

1.ClassPathXmlApplicationContext 构造方法

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}


在这里插入图片描述
调用了另一个构造方法

2. ClassPathXmlApplicationContext
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {
		/**
		 * 初始化父类
		 */
		super(parent);
		/**
		 * 设置本地资源配置
		 */
		setConfigLocations(configLocations);
		/**
		 * 完成Spring Bean的初始化
		 */
		if (refresh) {
			/**
			 * 构造方法
			 */
			refresh();
		}
	}

在这里插入图片描述
父上下文是空

设置配置文件setLocation

public void setConfigLocations(@Nullable String... locations) {
		/**
		 * 配置文件可以有多个循环处理
		 */
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				/**
				 * 把传进来的配置文件赋值给一个数组
				 */
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

refresh()核心方法


	public void refresh() throws BeansException, IllegalStateException {
		/**
		 * 加锁,说明并发执行,很多地方都有调用
		 * registerShutdownHook 也调用了
		 * close()方法也调有了,
		 * 容器在启动时,不能调Close的方法
		 */
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			/**
			 * 预初始化
			 */
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/**
			 *
			 * 创建BeanFactory工厂,告诉子类去刷新内部BeanFactory,
			 * 加载Bean信息,并封装为BeanDefinition,并注册到BeanDefinitionRegistry
			 * key-value key :bean的id value就是BeanDefinition
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/**
			 * 准备BeanFactory,进行一些设置
			 * Context的类加载器
			 */
			prepareBeanFactory(beanFactory);

			try {
				/**
				 * BeanFactory准备完成后,后置处理器增强,空方法
				 */
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);


				// Invoke factory processors registered as beans in the context.
				/**
				 * 实例化实现了BeanFactoryPostProcessor接口的类中构造方法
				 * 并调用用postProcessBeanFactory 方法
				 *
				 */
				invokeBeanFactoryPostProcessors(beanFactory);


				// Register bean processors that intercept bean creation.
				/**
				 *将实现了BeanPostProcessor的构造方法
				 */
				registerBeanPostProcessors(beanFactory);

				/**
				 * 初始化国际华资源MessageSource组牛
				 */
				// Initialize message source for this context.
				initMessageSource();

				/**
				 * 初始化事件派发器
				 */
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				/**
				 * 空方法
				 * 如果子类重写了这个方法就,调用子类重写的方法tomcat jetty之类的
				 */
				// Initialize other special beans in specific context subclasses.
				onRefresh();

				/**
				 * 注册应用监听器就是实现了ApplicationContextListener接口Bean
				 */
				// Check for listener beans and register them.
				registerListeners();
					/**
					 * 执行构造方法1
					 * setter方法2
					 * 实现了BeanNameAware接口的setBeanName方法3
					 * 实现了BeanFactoryAware接口的 setBeanFactory(BeanFactory beanFactory)方法4
					 * 实现了ApplicationContextAware接口的setsetApplicationContext 方法5
					 * 实现了BeanPostProcessor接口的postProcessBeforeInitialization方法6 ,AOP原理
					 * 标有PostConstruct注解的方法 7
					 * 实现了InitializingBean接口的afterPropertiesSet方法8
					 * 调用配置了init-method方法 9
					 * 实现了BeanPostProcessor接口的postProcessAfterInitialization方法 10
					 *
					 */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				/**
				 * 完成刷新Context,主要调用org.springframework.context.LifecycleProcessor接口onRefresh方法,发布事件ContextRefreshedEvent事件
				 */
				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				/**
				 * 销毁Bean
				 */
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				/**
				 * 重置Active标志为false
				 * this.active.set(false);
				 */
				// 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();
			}
		}
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章