spring源码解析(二):refresh()源码解析

文章目录

  • Spring refresh()源码解析
    • 1. prepareRefresh():容器刷新前的准备
    • 2. obtainFreshBeanFactory():初始化beanFactory,加载并解析配置
    • 3. prepareBeanFactory():设置beanFactory的属性
    • 4. postProcessBeanFactory(): BeanFactory创建完成后进行的后置处理工作
    • 5. invokeBeanFactoryPostProcessors():执行BeanFactoryPostProcessor的方法
    • 6. registerBeanPostProcessors():注册BeanPostProcessor(Bean的后置处理器)
    • 7. initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
    • 8. initApplicationEventMulticaster():初始化事件派发器
    • 9. onRefresh():子类重写这个方法,在容器刷新的时候可以自定义逻辑
    • 10. registerListeners():给容器中将所有项目里面的ApplicationListener注册进来
    • 11. finishBeanFactoryInitialization():初始化所有剩下的单实例bean
    • 12. finishRefresh():完成BeanFactory的初始化创建工作,IOC容器就创建完成

Spring refresh()源码解析

在spring源码解析(一):Spring启动流程中分析initWebApplicationContext接口时,进入到

public class ContextLoader {
    ...
    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
        ...
        configureAndRefreshWebApplicationContext(cwac, servletContext);
        ...
    }
}

而configureAndRefreshWebApplicationContext方法的执行:

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
		if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
			String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
			if (idParam != null) {
				wac.setId(idParam);
			}
			else {
				// Generate default id...
				wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
						ObjectUtils.getDisplayString(sc.getContextPath()));
			}
		}

		wac.setServletContext(sc);
		String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
		if (configLocationParam != null) {
			wac.setConfigLocation(configLocationParam);
		}

		ConfigurableEnvironment env = wac.getEnvironment();
		if (env instanceof ConfigurableWebEnvironment) {
			((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
		}

		customizeContext(sc, wac);
		wac.refresh();
	}

其中:refresh()方法是spring启动的核心,在其中完成了容器的刷新、beanFactory标准初始化、bean的初始化等。

Spring中AbstractApplicationContext抽象类的refresh()方法:

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
	
	... 
	
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//1 刷新前的预处理
			prepareRefresh();
            //2 获取BeanFactory;刚创建的默认DefaultListableBeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            //3 BeanFactory的预准备工作(BeanFactory进行一些设置)
			prepareBeanFactory(beanFactory);

			try {
		    	// 4 BeanFactory准备工作完成后进行的后置处理工作;
				postProcessBeanFactory(beanFactory);
 /**************************以上是BeanFactory的创建及预准备工作  ****************/
 
                // 5 执行BeanFactoryPostProcessor的方法;
				invokeBeanFactoryPostProcessors(beanFactory);
               
                //6 注册BeanPostProcessor(Bean的后置处理器)
				registerBeanPostProcessors(beanFactory);
                
                 // 7 initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
				initMessageSource();
                
                 // 8 初始化事件派发器
				initApplicationEventMulticaster();
               
                // 9 子类重写这个方法,在容器刷新的时候可以自定义逻辑;
				onRefresh();
               
                // 10 给容器中将所有项目里面的ApplicationListener注册进来
				registerListeners();

                // 11.初始化所有剩下的单实例bean;
				finishBeanFactoryInitialization(beanFactory);

                 // 12.完成BeanFactory的初始化创建工作;IOC容器就创建完成;
				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				destroyBeans();

				cancelRefresh(ex);

				throw ex;
			}
            finally {
				resetCommonCaches();
			}
		}
	}
	
	...
}

1. prepareRefresh():容器刷新前的准备

容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等

protected void prepareRefresh() {
        //设置context容器的启动时间
		this.startupDate = System.currentTimeMillis();
		//设置容器的当前状态
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}
		
        //初始化属性,留给子类覆盖实现
		initPropertySources();
		
        //验证必要属性是否都已经被解析
		getEnvironment().validateRequiredProperties();
		
        // 新建一个LinkedHashSet目的为了保存容器中一些事件。
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

其中,initPropertySources()方法:

protected void initPropertySources() {
		// For subclasses: do nothing by default.
	}

发现啥都没有,目的是为了给子类拥有修改属性的机会。

2. obtainFreshBeanFactory():初始化beanFactory,加载并解析配置

refresh()核心方法之一:初始化 BeanFactory,加载并解析配置

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//1.初始化beanFactory,并执行加载和解析配置操作
		refreshBeanFactory();
		//返回beanFactory实例
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

obtainFreshBeanFactory()方法中做了二件事:

  1. refreshBeanFactory():创建beanFactory、设置序列化Id、定制beanFactory、加载bean定义
  2. getBeanFactory():返回beanFactory实例

3. prepareBeanFactory():设置beanFactory的属性

创建完成beanFactory了之后,对beanFactory添加一些配置:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        //设置BeanFactory的类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
		//设置支持表达式解析器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        //添加部分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、ResourceLoader、ApplicationEventPublisher、ApplicationContext。
        通过以下方式:
        @autowired 
        BeanFactory beanFactory
        *********************************************************/ 
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        //添加BeanPostProcessor【ApplicationListenerDetector】后置处理器,在bean初始化前后的一些工作
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

        //添加编译时的Aspect
		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()));
		}

        //给BeanFactory中注册一些能用的组件
		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());
		}
	}

4. postProcessBeanFactory(): BeanFactory创建完成后进行的后置处理工作

上面对beanFactory进行了许多配置,现在需要对beanFactory进行一些处理:

@Override
	protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	    //添加一个ServletContextAwareProcessor到beanFactory中
		beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
		//在bean工厂自动装配的时候忽略一些接口。如:ServletContextAware、ServletConfigAware
		beanFactory.ignoreDependencyInterface(ServletContextAware.class);
		beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

        //注册WEB应用特定的域(scope)到bean工厂中,以便WebApplicationContext可以使用它们。比如"request", "session", "globalSession", "application"
		WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
		//注册WEB应用特定的Environment bean到bean工厂中,以便WebApplicationContext可以使用它们。如:"contextParameters", "contextAttributes"
		WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
	}

5. invokeBeanFactoryPostProcessors():执行BeanFactoryPostProcessor的方法

这里也是对beanFactory进行一些处理,调用所有的bean工厂处理器(BeanFactoryPostProcessor)对bean工厂进行一些处理:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

6. registerBeanPostProcessors():注册BeanPostProcessor(Bean的后置处理器)

注册用来拦截bean创建的BeanPostProcessor bean.这个方法需要在所有的application bean初始化之前调用。把这个注册的任务委托给了PostProcessorRegistrationDelegate来完成。

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<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 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<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		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);
			}
		}
		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));
	}

7. initMessageSource():初始化MessageSource组件(做国际化功能;消息绑定,消息解析)

初始化MessageSource接口的一个实现类。这个接口提供了消息处理功能。主要用于国际化/i18n

protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			// Make MessageSource aware of parent MessageSource.
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					// Only set parent context as parent MessageSource if no parent MessageSource
					// registered already.
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Using MessageSource [" + this.messageSource + "]");
			}
		}
		else {
			// Use empty MessageSource to be able to accept getMessage calls.
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
						"': using default [" + this.messageSource + "]");
			}
		}
	}

8. initApplicationEventMulticaster():初始化事件派发器

为这个context初始化一个事件广播器(ApplicationEventMulticaster

protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
			if (logger.isDebugEnabled()) {
				logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
			}
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
			if (logger.isDebugEnabled()) {
				logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
						APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
						"': using default [" + this.applicationEventMulticaster + "]");
			}
		}
	}

9. onRefresh():子类重写这个方法,在容器刷新的时候可以自定义逻辑

在AbstractApplicationContext的子类中初始化其他特殊的bean。其实就是初始化ThemeSource接口的实例。这个方法需要在所有单例bean初始化之前调用。

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

10. registerListeners():给容器中将所有项目里面的ApplicationListener注册进来

注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。

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 (earlyEventsToProcess != null) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

11. finishBeanFactoryInitialization():初始化所有剩下的单实例bean

完成bean的创建及初始化

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

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

12. finishRefresh():完成BeanFactory的初始化创建工作,IOC容器就创建完成

完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)

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

visio流程图下载地址:https://download.csdn.net/download/u011151359/11501392

上一章:spring源码解析(一):Spring启动流程
下一章:spring源码解析(三):refresh()核心之obtainFreshBeanFactory()方法解析

你可能感兴趣的:(spring源码之启动流程)