bean的创建过程--doGetBean
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //处理别名,提取对应的beanName final String beanName = this.transformedBeanName(name); /** * 检查缓存中或者实例工厂中是否有对应的实例 * 为什么会首先使用这段代码呢? * 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖 * Spring创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory */ //直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取 Object sharedInstance = this.getSingleton(beanName); Object bean; if (sharedInstance != null && args == null) { if (this.logger.isDebugEnabled()) { if (this.isSingletonCurrentlyInCreation(beanName)) { this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } //返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例 bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); } else { //只有在单例情况下才会尝试解决循环依赖,如果是原型模式下 则直接抛出如下异常 if (this.isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = this.getParentBeanFactory(); //如果beanDefinitionMap中也就是所有已经加载的类中不包括beanname则尝试从parentBeanFactory中检测 if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { String nameToLookup = this.originalBeanName(name); //递归到BeanFactory中寻找 if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } return parentBeanFactory.getBean(nameToLookup, requiredType); } if (!typeCheckOnly) { this.markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); this.checkMergedBeanDefinition(mbd, beanName, args); String[] dependsOn = mbd.getDependsOn(); String[] var11; //若存在依赖则需要递归实例化依赖的bean if (dependsOn != null) { var11 = dependsOn; int var12 = dependsOn.length; for(int var13 = 0; var13 < var12; ++var13) { String dependsOnBean = var11[var13]; if (this.isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } //缓存依赖调用 this.registerDependentBean(dependsOnBean, beanName); this.getBean(dependsOnBean); } } //实例化依赖的bean后便可以实例化mbd本身 //singleton模式的创建 if (mbd.isSingleton()) { sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { return AbstractBeanFactory.this.createBean(beanName, mbd, args); } catch (BeansException var2) { AbstractBeanFactory.this.destroySingleton(beanName); throw var2; } } }); bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { //protoType模式的创建 var11 = null; Object prototypeInstance; try { this.beforePrototypeCreation(beanName); prototypeInstance = this.createBean(beanName, mbd, args); } finally { this.afterPrototypeCreation(beanName); } bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { //指定的scope上实例化bean String scopeName = mbd.getScope(); Scope scope = (Scope)this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { AbstractBeanFactory.this.beforePrototypeCreation(beanName); Object var1; try { var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args); } finally { AbstractBeanFactory.this.afterPrototypeCreation(beanName); } return var1; } }); bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException var21) { 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", var21); } } } catch (BeansException var23) { this.cleanupAfterBeanCreationFailure(beanName); throw var23; } } //检查需要的类型是否符合bean的实际类型 if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return this.getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException var22) { if (this.logger.isDebugEnabled()) { this.logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", var22); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } else { return bean; } }
从上述代码可以看出bean的加载经历了一个复杂的过程,以上仅能粗略的了解整个Spring加载bean的过程。加载的步骤大致如下
1:转换对应的beanName
因为传入的参数不仅是beanName也可能是别名,也可能是FactoryBean,所以需要解析:去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&而使name="aa"。
取指定alias所表示的最终beanName,例如别名A指向名称B的bean则返回B;
2:尝试从缓存中加载单例
单例在spring容器内只会创建一次,后续获取都是从单例缓存中获取。如果获取不到则从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建的时候为了
避免循环依赖,在Spring中创建bean的原则是不等bean创建完就会将创建bean的ObjectFactory提早曝光,也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory
3:bean的实例化
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。
4:原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖
5:加测parentBeanFactory
如果缓存中没有取到则直接转到父类工厂上加载。
6:将存储xml配置文件的GernericBeanDefinition转换为RootBeanDefinition
7:寻找依赖
8:针对不同的scope进行bean的创建
9:类型转换
缓存池获取bean实例
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //一级缓存:存放的是已经完成实例化,属性填充和初始化步骤的单例bean实例 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) { synchronized(this.singletonObjects) { //二级缓存:存放的是提前暴露的单例bean实例,可能是代理对象,也可能是未经代理的原对象,但都还没有完成初始化的步骤 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { //三级缓存:存放的是ObjectFactory的匿名内部类实例 ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName); if (singletonFactory != null) { //回调ObjectFactory#getObject方法获取提前暴露的引用 singletonObject = singletonFactory.getObject(); //移入二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); //移除三级缓存 this.singletonFactories.remove(beanName); } } } } return singletonObject != NULL_OBJECT ? singletonObject : null; }
作者:
不二尘
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。