SpringIOC源码分析

前言 

Spring容器相当于一个大水桶,里面装了很多bean。这里的bean是简单的POJO对象,它们讲注入的控制权交给了容器(IOC),由容器完成依赖的注入。

正题

在Spring中,有两种容器,一种是以BeanFactory为实现的简单容器,另一种是以ApplicationContext为实现的高级容器,由于ApplicationContext是继承自BeanFactory接口的,所以ApplicationContext拥有BeanFactory的全部功能,并且加以扩展。这里就以AnnotationConfigApplicationContext为例,进入到源码的剖析。

启动类

自定义一个User类,创建AnnotationConfigApplicationContext容器加载并获取到生成的对象。

	public static void main(String[] args) {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationContextApp.class.getPackage().getName());
		User user = applicationContext.getBean(User.class);
		user.sayHell();
	}

在AnnotationConfigApplicationContext的构造器中,很清晰的可以看到容器的执行流程,第一步是初始化AnnotationConfigApplicationContext对象,这里主要是创建读取器reader和扫描器scanner。接着是扫描路径下的所有被标注需要注入的类,并且这些类转换为BeanDefinition保存在容器中。最后再调用refresh()将需要提前初始化的bean进行实例化。

	public AnnotationConfigApplicationContext(String... basePackages) {
		// 初始化容器
        this();
        // 扫描路径下需要注入的class
		scan(basePackages);
        // 刷新容器,初始化Bean对象
		refresh();
	}

 扫描

时序图

首先使用ClassPathBeanDefinitionScanner来扫描传入的路径,以获取到需要注入的bean对象。

	public int scan(String... basePackages) {
		int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
        // 具体的扫描逻辑
		doScan(basePackages);

		// 注册注解处理器,如果必要的话
		if (this.includeAnnotationConfig) {
			AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
		}

		return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
	}

根据Spring的传统惯例,我们可以知道具体的扫描逻辑在doScan当中。在doScan中,可以看到具体的BeanDefinition注册逻辑了。首先是从basePackage中进行解析,解析出来BeanDefinition,接着继续填充BeanDefinition的name等属性,检测到还有注册该BeanDefinition的话,就调用注册的逻辑。其中比较重要的就是findCandidateComponents方法,在这一步就完成了BeanDefinition的创建。

	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
		for (String basePackage : basePackages) {
			// 加载资源文件并解析成BeanDefinition
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				// 生成bean的名称
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				// 检测是否和已经注册bean冲突
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					// 注册bean
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
	}

这里就是将传入路径转换为扫描的匹配的路径,将扫描到的class转换为Resource,并解析出来MetadataReader,最终创建ScannedGenericBeanDefinition以供后续的注册。

	private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
		Set<BeanDefinition> candidates = new LinkedHashSet<>();
		try {
            // 转换扫描路径
			String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
					resolveBasePackage(basePackage) + '/' + this.resourcePattern;
			Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
			boolean traceEnabled = logger.isTraceEnabled();
			boolean debugEnabled = logger.isDebugEnabled();
			for (Resource resource : resources) {
				if (traceEnabled) {
					logger.trace("Scanning " + resource);
				}
				if (resource.isReadable()) {
					try {
						MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
						if (isCandidateComponent(metadataReader)) {
							// 创建BeanDefinition对象
							ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
							sbd.setSource(resource);
							if (isCandidateComponent(sbd)) {
								if (debugEnabled) {
									logger.debug("Identified candidate component class: " + resource);
								}
								candidates.add(sbd);
							}
    ......

	}

接着继续回到ClassPathBeanDefinitionScanner的doScan方法中,走到最后registerBeanDefinition,将刚刚解析出来的BeanDefinition注册到容器中。

	protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
        // 调用工具类,向registry中注册
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
	}

使用工具类进行注册,继续往下走进入到BeanDefinitionReaderUtils中,该方法是通过调用registry的registerBeanDefinition来注册,这个的registry的实现是DefaultListableBeanFactory,大部分使用到的容器实现底层都是DefaultListableBeanFactory,这也是Spring中BeanFactory的默认实现。

	public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// 获取解析的<bean>元素的名称beanName
		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		/*
		 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		 * 开始向 IoC容器 注册 BeanDefinition对象
		 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
		 */
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 如果解析的<bean>元素有别名alias,向容器中注册别名
		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

进入到DefaultListableBeanFactory中,这里的注册逻辑也很清晰,判断目标BeanDefinition是否存在,如果存在则继续判断是否允许覆盖,如果BeanDefinition不存在,则向beanDefinitionMap中进行put,并且将bean name放入到beanDefinitionNames中。到此就完成了BeanDefinition的解析和注册,但是目前的容器当中,只有Bean的定义,并没有Bean的实例,还不能提供Bean的调用,在使用Bean之前,还需要完成对Bean的实例化工作。

	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		// 校验解析的BeanDefinition对象
		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// 注册的过程中需要线程同步,以辩证数据的一致性
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// beanDefinitionMap是IoC容器的主要体现,它是一个ConcurrentHashMap,
				// 直接存储了bean的唯一标示beanName,及其对应的BeanDefinition对象
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				// 将beanName注册到BeanDefinitionNames列表
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			// 重置所有已经注册过的BeanDefinition的缓存
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

刷新

整个扫描过程结束之后,Bean的信息被解析成BeanDefinition并添加到了容器中,后续的Bean实例化过程则在refresh中完成。这里就直接跳过其他方法直接分析Bean的初始化方法finishBeanFactoryInitialization。

时序图

进入到最核心的生成单例bean的refresh方法,refresh方法是定义ConfigurableApplicationContext中,具体的实现是在AbstractApplicationContext中,在Spring中代码的基本套路的每层代码各司其职,构成了模板方法的设计模式。

	public void refresh() throws BeansException, IllegalStateException {
		// 给容器的refresh加锁,避免容器在refresh阶段,进行初始化或者销毁操作
		synchronized (this.startupShutdownMonitor) {
			// 调用容器准备刷新,获取容器当前时间,同时给容器设置同步标示
			// Prepare this context for refreshing.
			prepareRefresh();

			// 告诉子类启动refreshBeanFactory()方法,BeanDefinition的配置文件资源
			// 载入子类的refreshBeanFactory()方法启动开始。
			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 为BeanFactory配置容器特性,例如类加载器、事件处理器等
			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// 为容器的某些子类指定特殊的BeanPost事件处理器
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// 调用所有注册的BeanFactoryPostProcessor的Bean
				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// 为BeanFactory注册BeanPost事件处理器。
				// BeanPostProcessor是Bean后置处理器,用于监听容器的触发事件。
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// 初始化信息源,和国际化相关
				// Initialize message source for this context.
				initMessageSource();

				// 初始化容器的事件传播器
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// 调用子类的某些特殊Bean初始化方法
				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// 为事件传播器注册事件监听器.
				// Check for listener beans and register them.
				registerListeners();

				// 初始化Bean,并对lazy-init属性进行处理
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// 初始化容器的生命周期事件处理器,并发布容器的生命周期事件
				// 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();

				// 取消refresh操作,重置容器的同步标示
				// 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中preInstantiateSingletons方法进行预先实例化所有的非惰性(non-lazy)bean。这个方法是定义在ConfigurableListableBeanFactory接口中,此接口是对ConfigurableBeanFactory接口的扩展,提供修改BeanDefinition以及初始化等功能。

在preInstantiateSingletons中的初始化过程就是遍历所有的BeanDefinition,对非惰性bean调用getBean方法。

	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// 获取所有的bean定义的名字,并保存在集合List里面
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 测法所有非延迟单例bean的实例化
		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			// 触发所有适用bean的后初始化回调
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// 触发所有适用bean的后置初始化回调方法
		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

getBean方法则是最基础的BeanFactory接口的方法,实现是在AbstractBeanFactory中,调用之后继续调用doGetBean这才是真正获取bean对象的方法。

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

doGetBean中的代码非常多,主要是因为创建Bean时候的情况比较多,比如Singleton,Prototype,循环依赖等。不过目前我们只需要关注getSingleton中传递的lambda表达式createBean即可createBean的实现是在AbstractAutowireCapableBeanFactory中,具体的执行是在doCreateBean当中。

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		// 通过三种形式获取beanName
		// 一个是原始的beanName,一个是加了&的,一个是别名
		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		// 尝试从单例缓存集合里获取bean实例
		Object sharedInstance = getSingleton(beanName);
		// 如果先前已经创建过单例Bean的实例,并且调用getBean方法传入参数为空
		// 则执行if里面的逻辑
		// args之所以要求为空是因为如果有args,则需要做进一步复制,因此无法直接返回
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				// 如果Bean还在创建中,则说明是循环引用
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			// 如果是普通bean,直接返回,如果是FactoryBean,则返回他的getObject
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		// 若scope为prototype或者单例模式但是缓存中还不存在bean
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			// 如果scope为prototype并且显示还在创建中,则基本上是循环依赖的情况
			// 针对prototype的循环依赖,spring无解,直接抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			// 从当前容器中找不到指定名称的bean,此时递归去parentFactory查找
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				// 主要针对FactoryBean,将Bean的&重新加上
				String nameToLookup = originalBeanName(name);
				// 如果parent容器依旧是AbstractBeanFactory的实例
				// instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的自雷的一个实例
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					// 直接递归调用方法来查找
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					// 如果有参数,则委派父类容器根据制定名称和显式的参数查找
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					// 委派父级容器根据制定名称和类型查找
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					// 委派父级容器根据制定名称查找
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}
			// typeCheckOnly 是用来判断调用 getBean() 是否仅仅是为了类型检查获取bean,而不是为了创建Bean
			if (!typeCheckOnly) {
				// 如果不是仅仅做类型检查则是创建bean
				markBeanAsCreated(beanName);
			}

			try {
				// 将父类的BeanDefinition与自类的BeanDefinition进行合并覆盖
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 对合并的BeanDefinition做验证,主要看属性是否为abstract的
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 获取当前Bean所有依赖Bean的名称
				String[] dependsOn = mbd.getDependsOn();
				// 如果当前Bean设置了dependsOn的属性
				// depends-on用来制定Bean初始化及销毁时的顺序
				// <bean id=a class="test.A" depends-on="b"/>
				// <bean id=b class="test.b"/>
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 校验该依赖是否已经注册给当前bean,注意这里传入的key是当前的bean名称
						// 这里主要是判断是否有一下这种类型的依赖:
						// <bean id="beanA" class="BeanA" depends-on="beanB"/>
						// <bean id="beanB" class="BeanB" depends-on="beanA"/>
						// 如果有直接报异常
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 缓存依赖调用,注意这里传入的key是被依赖的bean名称
						registerDependentBean(dep, beanName);
						try {
							// 递归调用getBean方法,注册Bean之前的依赖(如C需要晚于B初始化,B需要晚于A初始化)
							// 初始化依赖的Bean
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				// 如果BeanDefinition为单例
				if (mbd.isSingleton()) {
					// 这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							// 显式从单例缓存中删除bean实例
							// 因为单例模式下为了解决循环依赖,可能它已经存在了,所以将其销毁。
							destroySingleton(beanName);
							throw ex;
						}
					});
					// 如果是普通bean,直接返回,是FactoryBean,返回它的getObject
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					// Prototype每次都会创建一个新的对象
					Object prototypeInstance = null;
					try {
						// 默认的功能是注册大年创建的prototype对象为正在创建中
						beforePrototypeCreation(beanName);
						// 创建原型对象实例
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						// 默认的功能是讲先前注册的正在创建中的Bean信息给抹除掉
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				// 要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
				// 配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
				// 比较常用,如:request、session、application等生命周期
				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					// Bean定义资源中没有配置生命周期范围,则Bean定义不合法
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							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 if required type matches the type of the actual bean instance.
		// 对创建的Bean实例对象进行类型检查
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

在doCreateBean当中,首先createBeanInstance创建出来bean的实例并且用BeanWrapper进行包装,此时的bean仅仅是被创建出来,里面的属性值为空,调用populateBean来装配bean中的属性值,随后调用initializeBean对bean进行AOP增强。这时的bean才是真正具有属性值的bean,也就是可以对外提供服务的对象了。将创建出来的bean返回给上一层的DefaultSingletonBeanRegistry,调用addSingleton将结果添加进容器中。

总结

Spring IOC部分的源码可能是大多数人第一次入门时的框架源码,里面包含了许多的分层以及设计模式,刚开始时尽量不要特别追求细枝末节,从整体上了解其中的设计和流程之后。如果再有多余的精力可以一点点的debug进去搞懂具体的实现细节。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值