Spring源码解析-IOC容器启动流程(三)

文章目录

  • 一、前言
  • 二、核心refresh()方法源码
  • 三、refresh()流程解析
    • 11. finishBeanFactoryInitialization(beanFactory)
      • 知识补充1:单实例(Singleton)
      • 知识补充2:懒加载(Lazy)
    • 12. finishRefresh()
    • 知识补充:LifecycleProcessor接口
  • 四、Bean的生命周期方法执行顺序
  • 五、IOC容器完成创建总结

一、前言

前两篇文章(Spring源码解析-IOC容器启动流程(一),Spring源码解析-IOC容器启动流程(二))分析完了容器的预处理工作,将必要的Bean都注册到了BeanFactory工厂中,所以这篇文章主要就是讲的剩下两步,也是最重要的两步,实例化Bean并完成一些后续操作。Bean的生命周期方法执行顺序可以在这里体现。

常用英译汉介绍:

英文 中文
Trigger 触发
Lifecycle 生命周期
Singleton 单实例
Prototype 多实例
Abstract 抽象的
Refresh 刷新
Post 后置的
Processor 处理器
Init(initialize) 初始化
Invoke 执行

了解这些常见的词汇后,看到类名、方法名和源码上的注释就可以大体猜出来干什么用的,这对阅读源码帮助很大。

二、核心refresh()方法源码

/*AbstractApplicationContext.class*/
@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.
		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;
		}

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

本篇要讲解finishBeanFactoryInitialization(beanFactory)和finishRefresh()两个方法。

三、refresh()流程解析

大部分的解析会直接写在源码注释上,请耐心阅读!

11. finishBeanFactoryInitialization(beanFactory)

这是相当关键的一步,几乎所有的单实例非懒加载Bean都会在这一步里创建完成。

知识补充1:单实例(Singleton)

Bean的scope有两种,一种是singleton,另外一种是prototype。分别是单实例,多实例。当用户多次调用getBean时,单实例Bean每次返回的同一个对象,而多实例Bean会在每次getBean时创建一个对象。所以容器创建时会将单实例Bean实例化。

知识补充2:懒加载(Lazy)

懒加载也叫延迟加载,容器创建时不加载,等到被调用getBean时再加载。使用方法就是在配置的Bean方法上写一个@Lazy注解,具体的不详细介绍了。

进入方法:

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// 初始化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));
	}
	
	// 如果没有bean后置处理器,注册一个默认的嵌入式值解析器,不重要
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
			@Override
			public String resolveStringValue(String strVal) {
				return getEnvironment().resolvePlaceholders(strVal);
			}
		});
	}

	// 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器,不重要
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// 停止使用临时类加载器进行类型匹配,不重要
	beanFactory.setTempClassLoader(null);

	// 缓存所有的bean定义,不希望有更改(冻结bean配置),不重要
	beanFactory.freezeConfiguration();

	// 初始化所有剩余的非懒加载的单实例bean,核心!!
	beanFactory.preInstantiateSingletons();
}

进入核心方法preInstantiateSingletons()

@Override
public void preInstantiateSingletons() throws BeansException {

	// 获取所有的bean定义信息
	List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

	// 触发所有的非懒加载单例bean初始化
	for (String beanName : beanNames) {
		// 将bean进行一次类型转换
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		// 如果bean不是抽象的,是单例的,而且不是懒加载的
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			// 判断这个Bean是不是属于FactoryBean,如果是的,就用工厂的一套流程来初始化
			if (isFactoryBean(beanName)) {
				final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
				boolean isEagerInit;
				if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
					isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
						@Override
						public Boolean run() {
							return ((SmartFactoryBean<?>) factory).isEagerInit();
						}
					}, getAccessControlContext());
				}
				else {
					isEagerInit = (factory instanceof SmartFactoryBean &&
							((SmartFactoryBean<?>) factory).isEagerInit());
				}
				if (isEagerInit) {
					getBean(beanName);
				}
			}
			// 若不是工厂方法,进入下面的getBean,重点!!!
			else {
				getBean(beanName);
			}
		}
	}

	// 一些后置回调方法
	......
}

getBean这个方法我们第一次使用Spring就应该见到过,用它来获取bean,例如

ApplicationContext application = new AnnotationConfigApplicationContext(MyConfig.class);
Woof woof= application.getBean("woof");
woof.wooooooooooow();
application.close();

那就继续进入getBean(beanName)方法一探究竟

public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

发现里面封装的一个doGetBean方法,那就继续进入方法,这个方法有点长,请耐心读注释。

protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
	// bean名字转换,去掉&(原工厂名前置是&)
	final String beanName = transformedBeanName(name);
	Object bean;

	// 检查singletonObjects中是否有这个bean的对象,以免重复创建
	Object sharedInstance = getSingleton(beanName);
	if (sharedInstance != null && args == null) {
		// 如果在singletonObjects找到了,直接赋值进去
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	// 没找到那就要自己创建了
	else {
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// 检查一些父工厂的定义,SpringMVC整合后会用到的工厂嵌套。
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}

		// 创建标记,标识这个已经创建了,防止多线程重复创建
		if (!typeCheckOnly) {
			markBeanAsCreated(beanName);
		}

		try {
			// 对bean信息做个验证
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// 保证当前bean所依赖的bean都已经初始化
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				// 如果依赖bean列表不为空,则初始化所有的依赖bean
				for (String dep : dependsOn) {
					// 如果循环依赖,这又是无穷递归了,嘿嘿,抛异常
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					registerDependentBean(dep, beanName);
					getBean(dep);
				}
			}

			// 此时,bean所依赖的bean都初始化完成了,现在可以安全的初始化了
			// 如果bean是单实例的
			if (mbd.isSingleton()) {
				// 匿名内部类写法,起作用的是createBean方法
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					@Override
					public Object getObject() throws BeansException {
						try {
							// 在这里创建的bean,进入此方法
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}
			......
			......
			}
		}
		catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
	}

	return (T) bean;
}

进入createBean(beanName, mbd, args)方法

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
	RootBeanDefinition mbdToUse = mbd;

	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	mbdToUse.prepareMethodOverrides();
	
	// 给Bean后置处理器一个机会,返回一个代理对象
	Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
	if (bean != null) {
		return bean;
	}
	// 如果没有返回代理对象,就调用doCreateBean方法创建对象
	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
	return beanInstance;
}

进入doCreateBean(beanName, mbdToUse, args)方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

	// Instantiate the bean.
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		// 创建出了Bean实例,执行了构造方法!!!
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
	mbd.resolvedTargetType = beanType;

	// 允许后置处理器来修改bean定义
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			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) {
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// 给bean的属性填充值,包括set方法,自动注入!!!
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			/** 初始化bean(包含了重要的生命周期顺序!!!)
			 *  1. 执行xxxAware方法
			 *  2. 执行后置处理器postProcessBeforeInitialization方法
			 *  3. 执行初始化方法,初始化方法有三种:
			 *   1) bean中指定的init-method
			 *   2) bean中实现的@PostConstruct方法
			 *   3) bean实现了InitializingBean接口中的afterPropertiesSet方法
			 *  4. 执行后置处理器postProcessAfterInitialization
			 */
			// 其实我很想进入这个办法让读者能看到这些操作的执行顺序的,但是
			// 需要深入的层太多了,不方便po源码,所以只好在这里小总结下流程 
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	}
	catch (Throwable ex) {
	}

	...

	// 注册销毁方法,比如DisposableBean接口中的destory。容器关闭才调用
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

于是doCreateBean就返回了一个实例Bean,已经注入了属性,并完成了各种初始化方法和各种后置处理方法。

此方法后,所有的单实例bean都被doCreateBean创建出来了,并把创建的Bean添加到缓存中singletonObjects。IOC容器也差不多创建好了。

12. finishRefresh()

完成最后的refresh操作。

进入方法:

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

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

第一句是initLifecycleProcessor(),执行初始化LifecycleProcesso。

知识补充:LifecycleProcessor接口

在Spring中提供了Lifecle接口,Lifecycle 中包含start/stop方法,实现此接口后Spring会保证在启动的时候调用其start方法开始生命周期,并在Spring关闭的时候调用 stop方法来结束生命周期。

public interface Lifecycle {  
  void start();  
  void stop();  
  boolean isRunning();  
} 

当ApplicationContext自身启动和停止时,它将自动调用上下文内所有生命周期的实现。通过委托给LifecycleProcessor来做这个工作。注LifecycleProcessor继承了Lifecycle接口。它也增加了两个其他的方法来与上下文交互,使得可以刷新和关闭。

public interface LifecycleProcessor extends Lifecycle {  
  void onRefresh();  
  void onClose();  
}  

那为什么要用LifecycleProcessor 把Lifecycle包装一遍呢?

  1. 因为Lifecycle的start(), stop()方法都要手动调用,而LifecycleProcessor提供了回调方法供开关ApplicationContext时自动调用。
  2. 多个Lifecycle的调用是有一定的顺序要求的,比如一个类依赖于另一个类,那么另一个类就要先执行。而LifecycleProcessor恰好提供了getPhase()来控制开关的顺序。

第二步getLifecycleProcessor().onRefresh(),拿到前面定义的生命周期处理器,回调onRefresh()。

第三步就是publishEvent(new ContextRefreshedEvent(this)),发布事件。

最后一步不重要。

四、Bean的生命周期方法执行顺序

将finishBeanFactoryInitialization(beanFactory)中描述了Bean生命周期的执行顺序,这里做一个小总结。

  1. 创建BeanFactory
  2. 执行BeanDefinitionRegistryPostProcessor接口方法
  3. 执行BeanFactoryPostProcessor接口方法
  4. 调用Bean的构造方法
  5. 设置属性(set,自动注入)
  6. 执行各种xxxAware方法
  7. 调用BeanPostProcessor接口的postProcessBeforeInitialization方法
  8. 执行初始化方法(分三种,上面有介绍)
  9. 调用BeanPostProcessor接口的postProcessAfterInitialization方法
  10. 容器关闭时,调用DisposableBean接口的销毁方法
  11. 执行destroy-method方法

这里我用转一张别的博客的图,我认为能很好的表明执行流程:
Spring源码解析-IOC容器启动流程(三)_第1张图片

五、IOC容器完成创建总结

  1. 获取所有未实例化的Bean
  2. 判断是否单实例,非抽象,非懒加载
    (1) 不满足其中一点,直接走其他流程(比如多实例创建流程)
  3. 尝试从缓存中找是否存在这个bean,如果有,直接返回
  4. 找不到的话,开始创建bean
  5. 执行bean的生命周期(第四步有总结)
  6. 将创建的bean加入到单实例对象缓存中
  7. 初始化和生命周期有关的后置处理器LifecycleProcessor
  8. 调用onRefresh()回调方法
  9. 发布容器刷新完成事件

你可能感兴趣的:(Spring)