5 bean的加载
以applicationContext.getBean("text")为入口,开始bean的加载。
AbstractBeanFactory public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { //提取对应的beanName String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. /** * 检查缓存中或者实例工厂中是否有对应的实例 * 为什么首先会使用这段代码呢, * 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖 * Spring创建bean的原则是不等bean创建完成就会创建bean的ObjectFactory提早曝光 * 也就是将ObjectFactory加入到缓存中,一旦下一个bean创建需要依赖上个bean则直接使用ObjectFactory */ //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { 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 + "'"); } } //返回对应的实例,有时候存在诸如BeanFacotry的情况并不是直接返回实例本身而是返回指定方法的实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //只有在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在 //A中有B属性,B中有A属性,那么依赖注入的时候,就会产生A中还未创建完成的时候 //因为对于B的创建再次返回创建A,造成循环依赖,也就是下面这种情况。 //是否正在创建(检测scope=property的循环依赖) if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //如果beanDefinitionMap中也就是所有已经加载的类中不包括beanName则尝试从 //parentBeanFactory中检测 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. //递归到BeanFactory中寻找 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); } } //如果不是仅仅做类型检查那么创建bean,这里要进行记录 if (!typeCheckOnly) { markBeanAsCreated(beanName); } StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate") .tag("beanName", name); try { if (requiredType != null) { beanCreation.tag("beanType", requiredType::toString); } //将存储XML配置文件的GernericBeanDefinition转换为RootBeandefinition,如果指定 //BeanName是子bean的话同时会合并父类的相关属性 RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); //若存在依赖则需要递归实例化依赖的bean if (dependsOn != null) { 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); try { getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. //实例化依赖的bean后便可以实例化mba本身了 //singleton模式的创建 if (mbd.isSingleton()) { 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. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. //prototype模式的创建(new) Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //指定scope上的实例化bean String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } 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, () -> { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new ScopeNotActiveException(beanName, scopeName, ex); } } } catch (BeansException ex) { beanCreation.tag("exception", ex.getClass().toString()); beanCreation.tag("message", String.valueOf(ex.getMessage())); cleanupAfterBeanCreationFailure(beanName); throw ex; } finally { beanCreation.end(); } } // 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; }
加载Bean过程中大致逻辑:
1.转换对应的beanName
因为传入的beanName可能是别名,也可能是FactoryBean,所以需要进行一系列的解析。解析包括:
- 去除FactoryBean的修饰符,也就是如果name="&aa",那么会去除&
- 取指定的alias所表示的最终beanName,例如别名A指向别名B,别名B指向别名C的Bean,那么返回C。
2.尝试从缓存中加载单例
单例在Spring同一个容器中只会被创建一次,后续在获取bean,直接从单例缓存中获取了。因为创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直接使用ObjectFactory。
3.bean的实例化
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化,这里有必要强调一下,缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean。举个例子,假如我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。
4.原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在A中有B属性,B中有A属性,那么依赖注入的时候,就会产生A中还未创建完成的时候因为对于B的创建再次返回创建A,造成循环依赖。isPrototypeCurrentlyInCreation(beanName)判断true。
5.检测parentBeanFactory
如果缓存中没有数据的话直接转到父类工厂上去加载。需要满足两个条件,parentBean-Factory != null、当前加载的XML配置文件中不包含beanName所对应的配置。满足条件后到parentBeanFactory中getBean。
6.将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
因为XML配置文件中读取的bean信息是存储在GenericBeanDefinition中的,但是所有的bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换,转换的同时如果父类bean不为空,则会合并一些父类的属性。
7.寻找依赖
因为bean的初始化过程中可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean,那么这个时候就有必要加载依赖的bean,所以,在Spring的加载顺序中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖。
8.针对不同的scope进行bean的创建
Spring中存在不同的scope,默认是singleton,但是还有一些其他的配置比如prototype,request...,根据不同的配置进行不同的初始化策略。
9.类型转换
。。。。。。bird

浙公网安备 33010602011771号