当前位置:   article > 正文

Spring源码:加载流程概览_spring 源码怎么看是加载完成

spring 源码怎么看是加载完成

Spring源码:加载流程概览


一个简单的xml配置入口函数:

    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object object = applicationContext.getBean("json");
        System.out.println(object.toString());
  • 1
  • 2
  • 3

从这个入口出发,即ClassPathXmlApplicationContext的构造方法,可以窥见Spring容器启动的过程。但是Spring太庞大了,直接进去看源码容易绕晕。先放几张类图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TsQV5JWb-1591204469307)(/home/adam/documents/typora/ClassPathXmlApplicationContext.png)]

  1. ApplicationContext是一个接口,但不是顶层接口,他继承自HierarchicalBeanFactory, ListableBeanFactory, ApplicationEventPublisher, ResourcePatternResolver, MessageSource接口。

ClassPathXmlApplication(String configLocation)

跟踪构造方法:

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}
	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
		super(parent);  (1)
		setConfigLocations(configLocations);  (2)
		if (refresh) {
			refresh();  (3)
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(1) 中调用父类构造函数,即AbstractApplicationContext的属性parent父上下文, resourcePatternResolver进行初始化。

(2) 设置配置文件路径,在AbstractRefereshableConfigApplicationContext中的属性String[] configLocations。

(3) 刷新上下文,也就是最重要的构建Spring的方法了。refresh方法是继承自AbstractApplicationContext,比较重要直接贴代码:

AbstractApplicationContext.refresh()

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				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) {
				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52

可以看到,基本都是protected方法,子类可以覆盖自己的行为; 而且通过startupShutdownMonitor上对象锁。接下来就挨个看看这些方法。


(1) AbstractApplicationContext.prepareRefresh()

准备刷新上下文,记录日志,active标志。

protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();

		synchronized (this.activeMonitor) {
			this.active = true;
		}

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

最后的logger.info("Refreshing "+this)会打印出当前上下文对象的实例,可查看toString源码,默认为Class@hash。不过在Spring mvc项目中会将displayName设成"Root WebApplicationContext",看不到实际的上下文类型。


(2) AbstractApplicationContext.obtainFreshBeanFactory()

获取并初始化BeanFactory,加载BeanDefinition。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其中refreshBeanFactory即设置BeanFactory了。

AbstractRefreshableApplicationContext.refreshBeanFactory()

@Override
	protected final void refreshBeanFactory() throws BeansException {
		//销毁先前的BeanFactory
        if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();   //创建DefaultListableBeanFactory实例
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);    //初始化配置
			loadBeanDefinitions(beanFactory);    //加载BeanDefinition,即读取xml文件中的bean为BeanDefinition
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

createBeanFactory创建DefaultListableBeanFactory类型的BeanFactory,并将继承自AbstractBeanFactory的parentBeanFactory属性设置为null。在父类AbstractAutowireCapableBeanFactory构造方法中指定了三个忽略的依赖接口:

	public AbstractAutowireCapableBeanFactory() {
		super();
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

将BeanNameAware三个接口添加到ignoredDependencyInterfaces属性中,尚不清楚这个属性干啥的。Aware系列接口一般表示对什么上下文有感知,例如实现BeanFactoryAware接口可以讲BeanFactory注入,实现ApplicationContextAware可以将ApplicationContext注入。

customizeBeanFactory进行一些初始化配置,例如循环引用,@Qualifier解析器等。

loadBeanDefinitions加载BeanDefinition到BeanFactory中。XmlBeanDefinitionReader的loadBeanDefinitions方法从先前设置的Resource[] configResources和String[] configLocations读取配置,这里只有configLocations有值。如果没有设置configLocations,Spring有一个默认值,查看源码就看到了,默认为/WEB-INF/${namespace}.xml,而且默认的namespace=applicationContext。

DefaultBeanDefinitionDocumentReader.processBeanDefinition

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// Register the final decorated instance.
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// Send registration event.
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

通过BeanDefinitionParserDelegate将Element元素解析为BeanDefinitionHolder,并注册到Registry中。BeanDefinitionRegistry是一个用于注册BeanDefinition的接口,这里的Registry实际上就是前面创建的DefaultListableBeanFactory,实现了BeanDefinitionRegistry接口,把所有的BeanDefinition和名称注册到下面两个属性中。

	/** Map of bean definition objects, keyed by bean name */
	private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
	/** List of bean definition names, in registration order */
	private final List<String> beanDefinitionNames = new ArrayList<String>();
  • 1
  • 2
  • 3
  • 4

加载BeanDefinition后,将BeanFactory实例赋值给AbstractRefreshableApplicationContext的beanFactory属性,即refresh完成。(synchronized this.beanFactoryMonitor,Spring好多操作都要上同步锁)


(3) AbstractApplicationContext.prepareBeanFactory

对BeanFactory初始化操作。

        beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));

		// Configure the bean factory with context callbacks.
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		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);
        
        //... 以及LoadTimeWeaverProcessor, 系统属性和环境变量。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

其中的ApplicationContextAwareProcessor是一个BeanPostProcessor,处理实现了部分Aware接口的Bean,将上下文注入。


(4) AbstractApplicationContext.postProcessBeanFactory

此方法没有实现。


(5) AbstractApplicationContext.invokeBeanFactoryPostProcessors

执行BeanFactoryPostProcessor处理。具体执行顺序为:

  • AbstractApplicationContext.beanFactoryPostProcessors中实现了BeanDefinitionRegistryPostProcessor的processor,执行postProcessBeanDefinitionRegistry方法
  • beanFactory中实现了BeanDefinitionRegistryPostProcessor的processor, 按照Order排序,执行postProcessBeanDefinitionRegistry方法
  • AbstractApplicationContext.beanFactoryPostProcessors中实现了BeanDefinitionRegistryPostProcessor的processor,执行postProcessFactory方法
  • beanFactory中实现了BeanDefinitionRegistryPostProcessor的processor, 按照Order排序,执行postProcessFactory方法
  • AbstractApplicationContext.beanFactoryPostProcessors中未实现BeanDefinitionRegistryPostProcessor的processor,执行postProcessFactory方法
  • beanFactory中实现了BeanFactoryPostProcessor的processor,按照Order排序,依次执行PriorityOrderedPostProcessor、OrderedPostProcessor、NonOrderedPostProcessor的postProcessFactory方法

这里涉及到的排序,即优先级顺序为PriorityOrdered一级优先,Ordered二级优先,PriorityOrdered, Ordered是两个接口。同级按照order值由大到小排序。


(6) AbstractApplicationContext.registerBeanPostProcessors

注册BeanPostProcessor。和执行BeanFactoryPostProcessor的逻辑有点类似,也用到了排序,不过这里只是注册到BeanFactory中。注册顺序为:

  • beanFactory中实现了BeanPostProcessor,PriorityOrdered的processor,按优先级顺序注册
  • beanFactory中实现了BeanPostProcessor,Ordered的processor,按优先级顺序注册
  • beanFactory中实现了BeanPostProcessor的processor,按顺序注册
  • beanFactory中实现了MergedBeanDefinitionPostProcessor的processor(内部processor),按优先级顺序注册

这里手动设置一个BeanPostProcessorChecker,将当前beanPostProcessor的数量传入构造方法。


(7) AbstractApplicationContext.initMessageSource

设置messageSource,用来处理message,国际化文本等,默认为DelegatingMessageSource


(8) AbstractApplicationContext.initApplicationEventMulticaster

设置应用事件广播器,默认为SimpleApplicationEventMulticaster


(9) AbstractApplicationContext.onRefresh

此方法没有实现。


(10) AbstractApplicationContext.registerListeners

注册ApplicationListener类型的监听处理器到(8)创建的ApplicationEventMulticaster,注册顺序为:

  • AbstractApplicationContext.applicationListeners
  • beanFactory中实现了ApplicationListener的listener

(11) AbstractApplicationContext.finishBeanFactoryInitialization

真正完成Bean的初始化,BeanPostProcessor执行等。

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

		// 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();
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Bean初始化逻辑主要在preInstantiateSingletons中,对beanDefinitionMap同步锁初始化。最终调用AbstractAutowireCapableBeanFactory.doCreateBean方法,比较长。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory() {
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90

applyMergedBeanDefinitionPostProcessors这里,执行MergedBeanDefinitionPostProcessor,即前面提到的“内部处理器”。MergedBeanDefinitionPostProcessor的一个实现类是AutowiredAnnotationBeanPostProcessor,处理@Autowired注解的属性和方法,将依赖的对象或者参数注入。

populateBean填充属性。

initializeBean调用Aware方法、BeanPostProcessor、初始化方法。

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}				
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

可以看到,初始化方法是先调用afterPropertiesSet,然后在调用自定义的init-method方法。


(12) AbstractApplicationContext.finishRefresh

上下文刷新完成,执行LifecycleProcessor.onRefresh方法,发布刷新完成的事件。

protected void finishRefresh() {
		// Initialize lifecycle processor for this context.
		initLifecycleProcessor();

		// Propagate refresh to lifecycle processor first.
		getLifecycleProcessor().onRefresh();

		// Publish the final event.
		publishEvent(new ContextRefreshedEvent(this));
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

initLifecycleProcessor注册LifecycleProcessor,默认为DefaultLifecycleProcessor。

getLifecycleProcessor().onRefresh将实现LifeCycle的Bean执行start方法。

publishEvent发布事件,使applicationEventMulticaster向applicationListeners通知事件。而且这里通过Spring的taskExecutor并行通知,并且向父上下文也通知。


坑点:afterProperties开启线程初始化,但依赖的Bean还没有初始化,死锁发生在synchronized singletonObjects。
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/1014641
推荐阅读
相关标签
  

闽ICP备14008679号