Spring的getBean的流程(源码级讲解 + 核心流程总结)

如果你正打算深入学习Spring,但是不知从何学起,那么我强烈推荐你可以按照这个系列做一遍。本系列将Spring框架的各个部分从它庞杂的代码体系中抽取出来,然后对每一个部分进行讲解,并最终搭建成简易版Spring。我以人格保证:如果你可以坚持做下来,那么你对Spring这块的知识就基本都掌握清楚了! 附上该系列地址:https://blog.csdn.net/zhang_qing_yun/article/details/120084497
# getBean的流程 ## 源码
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
    
     
    // getBean 其实没做啥,都在 doGetBean 里
	return doGetBean(name, requiredType, null, false);
}
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {
    
         
    
    // 处理别名BeanName、处理带&符的工厂BeanName
	final String beanName = transformedBeanName(name);
	Object bean;  

	// 先尝试从缓存中获取Bean实例,这个位置就是三级缓存解决循环依赖的方法
	Object sharedInstance = getSingleton(beanName);   

	if (sharedInstance != null && args == null) {
    
    
		if (logger.isDebugEnabled()) {
    
    
			if (isSingletonCurrentlyInCreation(beanName)) {
    
    
				logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
    
    
				logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}        
        
        // 1. 如果 sharedInstance 是普通的 Bean 实例,则下面的方法会直接返回
        // 2. 如果 sharedInstance 是工厂Bean类型,则需要获取 getObject 方法,可以参考关于 FactoryBean 的实现类 
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}
	else {
    
    
		
        // 循环依赖有三种,setter注入、多实例和构造函数,Spring 只能解决 setter 注入,所以这里是 Prototype 则会抛出异常
		if (isPrototypeCurrentlyInCreation(beanName)) {
    
    
			throw new BeanCurrentlyInCreationException(beanName);
		}    

		// 1. 父 bean 工厂存在
        // 2. 当前 bean 不存在于当前bean工厂,则到父工厂查找 bean 实例
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    
    
			// 获取 name 对应的 beanName,如果 name 是以 & 开头,则返回 & + beanName
			String nameToLookup = originalBeanName(name);         
            
            // 根据 args 参数是否为空,调用不同的父容器方法获取 bean 实例
			if (args != null) {
    
    
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
    
    
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
		}       

        // 1. typeCheckOnly,用于判断调用 getBean 方法时,是否仅是做类型检查
        // 2. 如果不是只做类型检查,就会调用 markBeanAsCreated 进行记录
		if (!typeCheckOnly) {
    
    
			markBeanAsCreated(beanName);
		}
		try {
    
        
    
            // 从容器 getMergedLocalBeanDefinition 获取 beanName 对应的 GenericBeanDefinition,转换为 RootBeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 
            // 检查当前创建的 bean 定义是否为抽象 bean 定义
			checkMergedBeanDefinition(mbd, beanName, args);
			
            // 处理使用了 depends-on 注解的依赖创建 bean 实例
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
    
    
				for (String dep : dependsOn) {
    
       
                    // 监测是否存在 depends-on 循环依赖,若存在则会抛出异常
					if (isDependent(beanName, dep)) {
    
    
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}       
                    
                    // 注册依赖记录
					registerDependentBean(dep, beanName);
					try {
    
        
					    // 加载 depends-on 依赖(dep 是 depends-on 缩写)
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
    
    
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}  

			// 创建单例 bean 实例
			if (mbd.isSingleton()) {
    
        

			    // 把 beanName 和 new ObjectFactory 匿名内部类传入回调
				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);
			}      
            // 创建其他类型的 bean 实例
			else if (mbd.isPrototype()) {
    
    
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
    
    
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
    
    
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}
			else {
    
    
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
    
    
					throw new IllegalStateException("No Scope registered for scope name '" + 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;
		}
	}
	// 如果需要类型转换,这里会进行操作
	if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
    
    
		try {
    
    
			return getTypeConverter().convertIfNecessary(bean, requiredType);
		}
		catch (TypeMismatchException ex) {
    
    
			if (logger.isDebugEnabled()) {
    
    
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
	}    

    // 返回 Bean
	return (T) bean;
}

几个重要函数:

	protected String transformedBeanName(String name) {
    
    
		//如果beanName是以&开头的  则截取掉开头的&
		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
	}
	public String canonicalName(String name) {
    
    
		String canonicalName = name;
		// 循环的去获取别名,直到获取到真实的beanName
		//aliasA->aliasB->beanName
		String resolvedName;
		do {
    
    
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
    
    
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}
 
	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    
    
 
		//如果name是以&开头的 但是不是FactoryBean,则直接抛出异常
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
    
    
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}
 
		// 则beanInstance可能是一个普通的bean,也可能是一个FactoryBean
		// 如果是一个普通的bean,则直接返回
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
    
    
			return beanInstance;
		}
 
		//FactoryBean创建出bean实例返回
		Object object = null;
		if (mbd == null) {
    
    
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
    
    
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			if (mbd == null && containsBeanDefinition(beanName)) {
    
    
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

流程总结

getBean核心流程图

  1. 调用transformedBeanName函数处理Bean的名字,主要有两个目的:一是对FactoryBean的Name做一些处理(通常FactoryBean的名字前面会增加一个&符号用来和普通Bean的BeanName区分,但是在存储上没有差异),另一个是针对别名的处理,将其替换为真实的BeanName。
  2. 调用getSingleton函数从三级缓存中搜索要查找的Bean:
    1. 如果不为null,则说明已经创建过或者正在创建中(循环依赖就是在这里解决的)。这时如果获取到的Bean是普通Bean就会直接返回,getBean流程结束。如果获取到的是FactoryBean,则会先去缓存中查找该BeanName对应的FactoryBean是否生产过对象,如果有则直接返回,getBean流程结束;如果缓存中获取不到,说明该FactoryBean还没有生产过对象,则会调用该FactoryBean的getObject方法去生产一个Bean,然后将这个工厂Bean创造的Bean添加到缓存中(注意:这里的缓存并不是三级缓存中的任何一个,而是一个专门用于存放工厂Bean即FactoryBean创造出来的Bean的缓存,位于FactoryBeanRegistrySupport中,也就是说,FactoryBean存放于三级缓存中,它创造出来的Bean并不在三级缓存中,两者没有被缓存在同一个地方),然后将生产出来的Bean返回,getBean流程结束。
    2. 如果从缓存中获取到null,如果当前工厂的父工厂存在且当前工厂中没有该Bean的定义信息的话,就会去到父工厂中去执行getBean操作(这时如果创建对象也会保存在父工厂中),然后直接返回父工厂getBean的结果,getBean流程结束。如果没有父工厂或者当前工厂中存在该Bean的定义信息,就会去创建该Bean:首先,获取Bean的定义信息。然后处理该Bean通过@DependsOn注解指定的Bean(通过该注解可以指定Bean的加载顺序,优先加载指定的Bean),遍历这些指定的Bean的名字,调用getBean函数完成对这些Bean的加载。然后执行beforeSingletonCreation方法,将该Bean标记成正在创建状态;然后会去执行createBean方法的逻辑(详细解析可以看:创建Bean的流程);执行afterSingletonCreation方法,将bean从正在创建的状态中移除;然后调用addSingleton方法,将该Bean添加到一级缓存中,并删除它在二、三级缓存中的内容。Bean创建完成后,会去执行getObjectForBeanInstance方法,作用是如果该Bean是FactoryBean类型,就会去获取该FactoryBean要创造的对象,然后将其作为最终的对象并返回(注意:这里的创建逻辑是单例Bean的)。

猜你喜欢

转载自blog.csdn.net/zhang_qing_yun/article/details/120083309