IOC的工作过程

1.如何创建BeanFactory工厂

构建的入口在AbstractApplicationContext类的refresh方法中。

我们可以从一个例子来入手

	public class test {
		private ApplicationContext context;
		@Test
		public void test1(){
			context = new ClassPathXmlApplicationContext("applicationContext.xml");
			SomeBean someBean = (SomeBean) context.getBean("someBean");
			someBean.doSomething();
		}
	}

这是一个简单的Spring入门的程序。非常简单,通过xml文件,创建一个容器context,然后从容器中获取一个bean。

我们可以使用IDE追踪源码(Spring的源码的下载链接或者在官网下载)。

下面是ClassPathXmlApplicationContext类中的构造函数:

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

转向了另一个构造函数:

	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, 
			ApplicationContext parent)throws BeansException {
				super(parent);
				setConfigLocations(configLocations);
				//判断是否刷新
				if (refresh) {
					refresh();
				}
	}

我们可以进入这个refresh方法:

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//1.准备刷新
			prepareRefresh();

			// 2.创建内部容器,该容器负责Bean的创建和管理
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			
			prepareBeanFactory(beanFactory);

			try {
				postProcessBeanFactory(beanFactory);
				invokeBeanFactoryPostProcessors(beanFactory);
				registerBeanPostProcessors(beanFactory);
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				registerListeners();
				//实例化Bean实例的入口(后面会详细讲解——如何创建Bean实例并构建Bean的关系网)
				finishBeanFactoryInitialization(beanFactory);
				finishRefresh();
			}

			catch (BeansException ex) {
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}
		}
	}

我们发现此时我们进入了AbstractApplicationContext类的refresh方法,其实通过ClassPathXMLApplication的定义时,我们可以看到它继承了AbstractXmlApplicationContext类,一路追踪下去发现最后是继承了AbstractApplicationContext类。它们都没有对AbstractApplicationContext的refresh方法进行重写,所以会调用了AbstractApplicationContext的refresh方法。

1.准备刷新

初始化准备,即为Ioc容器的初始化过程做准备,该过程和 Spring的Environment有关。我们先不用关注。

2.创建内部容器

我们来关注一下AbstractApplicationContext的obtainFreshBeanFactory方法

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		//1.刷新Spring容器中内部的BeanFactory
		refreshBeanFactory();
		//2.得到内部的BeanFactory
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
		}
		return beanFactory;
	}

(1)刷新Spring容器中内部的BeanFactory

因为AbstractApplicationContext只是定义了refreshBeanFactory的抽象方法,它的子类AbstractRefreshableApplicationContext才实现了refreshBeanFactory的方法。ClassPathXmlApplicationContext继承的也是AbstractRefreshableApplicationContext的子类,所以这里执行的refreshBeanFactory就是AbstractRefreshableApplicationContext类中的refreshBeanFactory方法。

我们来看看代码:

	protected final void refreshBeanFactory() throws BeansException {
		//1.判断Spring容器中是否有BeanFactory,如果存在就销毁并关闭它。
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			//2.创建一个BeanFactory(默认创建一个DefaultListableFactory类作为内部BeanFactory)
			DefaultListableBeanFactory beanFactory = createBeanFactory();

			//3.设置BeanFactory的id,和外部的Spring容器一样
			beanFactory.setSerializationId(getId());
			
			//4.定制BeanFactory初始化,暂不关注
			customizeBeanFactory(beanFactory);
			
			//5.加载Bean实例
			loadBeanDefinitions(beanFactory);
			
			//6.将BeanFactory设置为Spring容器的内部BeanFactory
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error "
			 + getDisplayName(), ex);
		}
	}

(2)得到内部的BeanFactory

得到Spring内部的BeanFactory。

总结:我们可以通过一个流程图能清楚的看到创建BeanFactory的全过程
在这里插入图片描述

2.如何创建Bean实例并构建Bean的关系网

下面就是Bean的实例化代码(在上文中refresh方法的代码中我们有提到,创建完了BeanFactory),是从AbstractApplicationContext类的finishBeanFactoryInitialization方法开始的。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		//部分代码省略
		
		// 不使用TempClassLoader
		beanFactory.setTempClassLoader(null);

		// 禁止修改当前Bean的配置信息
		beanFactory.freezeConfiguration();

		// 实例化non-lazy-int类的bean
		beanFactory.preInstantiateSingletons();
	}

从上面的代码我们可以发现Bean的实例化是在BeanFactory中的preInstantiateSingletons方法中实现的。我们又进入到DefaultListableBeanFactory类中preInstantiateSingletons方法(关于为什么是DefaultListableBeanFactory类,上文创建BeanFactory已经讲过了)。我们来看代码(其中省略了部分不重要的代码):

public void preInstantiateSingletons() throws BeansException {
	//1.获取XML配置文件解析时,解析到的所有beanname
	List<String> beanNames;
	synchronized (this.beanDefinitionMap) {
		beanNames = new ArrayList<String>(this.beanDefinitionNames);
	}
	//2.遍历所有没有标注过lazy-init的singleton的beanname,创建bean
		//遍历beanNames保存的beanname
	for (String beanName : beanNames) {
		//利用beanname获取BeanDefinition
			//(XML解析时会生成BeanDefinition对象
			//将XML中的各属性添加到BeanDefinition的相关标志位中,比如abstractFlag,scope等)
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		//非abstract,非lazy-init的singleton bean才能需要在容器初始化阶段创建
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			//判断是否是FactoryBean
			if (isFactoryBean(beanName)) {
				//如果是,则会获取FactoryBean实例,FactoryBean前面会加一个&符号
				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);
				}
			}
			//非Factorybean,直接调用getBean方法。
			else {
				getBean(beanName);
			}
		}
	}
		// Trigger post-initialization callback for all applicable beans...
	for (String beanName : beanNames) {
		Object singletonInstance = getSingleton(beanName);
		if (singletonInstance instanceof SmartInitializingSingleton) {
			final SmartInitializingSingleton smartSingleton =
			 (SmartInitializingSingleton) singletonInstance;
			if (System.getSecurityManager() != null) {
				AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}
				}, getAccessControlContext());
			}
			else {
				smartSingleton.afterSingletonsInstantiated();
			}
		}
	}
}

我们可以发现这段代码又是调用了父类AbstractBeanFactory类中的 getBean完成了bean的创建和初始化。

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

紧接着又调用了父类AbstractBeanFactory类中doGetBean方法。

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args,
					 boolean typeCheckOnly)throws BeansException {
		//beanname转换,去掉FactoryBean的&前缀。
		final String beanName = transformedBeanName(name);
		Object bean;
		
		Object sharedInstance = getSingleton(beanName);
		//判断singleton bean是否创建好了,创建好了直接从内存中取出
		if (sharedInstance != null && args == null) {
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		//还没创建好
		else {
			//正在创建,则直接异常返回
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			
			//检查是否有beanname对应的BeanDefinition
				//得到父工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
				//检查没有找到的话,就看看父工厂中有没有BeanDefinition
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				//获取原始的name,包含了FactoryBeanName
				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 {
				//找到了beanName对应的BeanDefinition,合并parent的BeanDefinition(XML中的parent属性)
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 处理dependsOn属性
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					//遍历所有的dependOn bean,先要注册和创建依赖项的bean
					for (String dependsOnBean : dependsOn) {
						//check两个bean是不是循环依赖,spring不能出现bean的循环依赖
						if (isDependent(beanName, dependsOnBean)) {
							throw new BeanCreationException(mbd.getResourceDescription(), 
							beanName,"Circular depends-on relationship between '" +
							 beanName + "' and '" + dependsOnBean + "'");
						}
						//注册并创建依赖的bean
						registerDependentBean(dependsOnBean, beanName);
						getBean(dependsOnBean);
					}
				}

				// 处理scope属性
				if (mbd.isSingleton()) {
					//singleton,必须保证线程安全的情况下创建bean,保证单例
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						public Object getObject() throws BeansException {
							try {
								//反射创建bean实例,这个过程很复杂,稍后分析
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								//异常处理,清除bean
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					//获取bean实例
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				//多例的话,创建一个全新的实例
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						//创建前的回调
						beforePrototypeCreation(beanName);
						//反射创建bean实例,稍后分析
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						//创建后的回调,清除inCreation的标志
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				//其他scope的 值
				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					//scope属性不能接收空值
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; " +
								"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		//check创建的bean是否是requiredType指明的类型。如果不是,先转换,转成不成就只能类型不匹配抛出异常了
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
			catch (TypeMismatchException ex) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

调用了AbstractAutowireCapableBeanFactory类的createBean通过反射创建bean实例

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

		//处理bean中定义的覆盖方法,主要是xml:lookup-method或者replace-method。
			//标记override的方法为已经加载过的,避免不必要的参数检查开销
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}
		//调用BeanPostProcessors bean后处理器,
			//使得bean后处理器可以返回一个proxy bean,从而代替我们要创建的bean。
			//回调后处理器的postProcessBeforeInstantiation方法,
			//如果这个方法中返回了一个bean,也就是使用了proxy,则再回调postProcessAfterInitialization()方法。
			//之后返回这个Proxy bean即可。
		try {
			Object bean = resolveBeforeInstantiation(beanName, mbd);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}
		//doCreateBean创建bean实例,后面详细分析
		Object beanInstance = doCreateBean(beanName, mbd, args);
		return beanInstance;
	}

我们重点分析AbstractAutowireCapableBeanFactory类中的doCreateBean方法。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
		
		//创建bean实例,如果是singleton,先尝试从缓存中取,取不到则创建
		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);

		// 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<Object>() {
				@Override
				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);
			}
		}
	
		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()) {
						//抛出异常
					}
				}
			}
		}

		//  注册bean为可销毁的bean,bean销毁时,会回调destroy-method
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
		return exposedObject;
	}

使用AbstractAutowireCapableBeanFactory类中createBeanInstance 反射创建bean实例

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// 先创建class对象,反射的套路。利用bean的class属性进行反射,所以class属性一定要是bean的实现类
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		
		//class如果不是public的,则抛出异常。因为没法进行实例化
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}
		//使用FactoryBean的factory-method来创建,支持静态工厂和实例工厂
		if (mbd.getFactoryMethodName() != null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 无参数情况时,创建bean。调用无参构造方法。
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				//autowire创建 自动装配
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//普通创建
				return instantiateBean(beanName, mbd);
			}
		}

		// 有参数的情况时,创建bean。先利用参数的个数,类型等,确定最精确匹配的构造方法。
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 有参数时。又没有获取到构造方法,则只能调用无参数构造方法创建实例了
		return instantiateBean(beanName, mbd);
	}

AbstractAutowireCapableBeanFactory类中instantiateBean,使用无参构造方法,反射创建bean实例代码如下:

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
				beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
					@Override
					public Object run() {
						return getInstantiationStrategy().instantiate(mbd, beanName, parent);
					}
				}, getAccessControlContext());
			}
			else {
				//创建实例,关键点
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			//抛出异常
		}
	}

关键点在SimpleInstantiationStrategy类中的instantiate方法

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
		if (beanDefinition.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			//保证线程安全的情况下,获取Constructor
			synchronized (beanDefinition.constructorArgumentLock) {
				//获取构造方法或者factory-method
				constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
				//BeanDefinition中如果没有Constructor或者factory-method,则直接使用默认无参数的构造方法
				if (constructorToUse == null) {
					final Class<?> clazz = beanDefinition.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
								@Override
								public Constructor<?> run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						//获取默认无参数的构造方法
						else {
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			//使用上一步得到的Constructor,反射获取bean实例
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(beanDefinition, beanName, owner);
		}
	}

instantiate方法主要做两件事,确定Constructor或者factory-method 利用Constructor,反射创建bean实例。

猜你喜欢

转载自blog.csdn.net/jdfk423/article/details/82790009