您当前的位置: 首页 >  spring

恐龙弟旺仔

暂无认证

  • 0浏览

    0关注

    282博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Spring源码深度解析(XmlBeanFactory源码解析下)

恐龙弟旺仔 发布时间:2018-07-10 13:48:41 ,浏览量:0

前言:

    上文Spring源码深度解析(XmlBeanFactory源码解析上)介绍了XMLBeanFactory加载beans.xml的全过程

    简单总结一下就是:

        读取beans.xml为输入流;

        DOM解析xml文件为Document;

        Spring解析Document的Element为BeanDefinitionHolder;

        将beanName和BeanDefinitionHolder的键值对放入DefaultListableBeanFactory类的beanDefinitionMap中。

 

    本文接着上文来介绍

Student bean = (Student) bf.getBean("student");

    上述一句代码所实现的操作

 

注意:由于Bean的xml可配置项较多,生产Bean的方式也较多,纵观BeanFactory.getBean()相关操作的代码分叉较多,笔者不会分析所有的代码分支情况,只会按照最简约的模式来分析最核心的代码,这样不会迷失在代码的海洋里。。。

 

1.XMLBeanFactory的基本使用

    代码同 Spring容器的基本实现(XmlBeanFactory源码解析上) 1小结代码

 

2.写在分析XmlBeanFactory源码之前

    由上节可知,解析后的beanName和BeanDefinitionHolder的键值对放入DefaultListableBeanFactory类的beanDefinitionMap中,beanDefinitionMap结构是一个默认大小为256的ConcurrentHashMap

    按照最简单的实现方式:

    1)BeanFactory.getBean(String beanName)无非就是根据beanName从ConcurrentHashMap中获取对应的value值,也就是BeanDefinitionHolder实例

    2)获取BeanDefinitionHolder中的BeanDefinition,获取BeanDefinition对应的Class对象

    3)反射获取Class对象所对应的实体类对象bean

    4)返回调用

 

    由以上方式是可以获取beanName对应的bean实例,但是还有些问题需要我们来思考

    问题:

        * bean的实现由prototype和singleton的区别,如何区别实现?

        * bean的实现过程中,若依赖其他bean该如何加载?

        * 若bean之间循环依赖该如何解决?

        ...

3.XmlBeanFactory.getBean(String name)代码结构分析
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	protected  T doGetBean(
			final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

        // 1.转换name,因为name有可能是FactoryBean相关的name,也有可能是alias,所以需要判断
		final String beanName = transformedBeanName(name);
		Object bean;

		// 2.如果是单例模式创建的bean,如果bean已经被创建过则会放入singletonFactories,
        // 此时再获取则从singletonFactories中直接获取
		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 + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

        // 3.bean没有被创建过,重新开始创建
		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// parentBeanFactory默认为空,该段逻辑不走
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				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) {
                // 3.1将beanName添加到已创建的列表中,表明该bean已经在创建中了。
				markBeanAsCreated(beanName);    
			}

			try {
                // 3.2 根据beanName获取对应的BeanDefinition,然后重新包装成RootBeanDefinition
                // (重要方法,在这个方法里会从DefaultListableBeanFactory类的beanDefinitionMap中获取对应的BeanDefinitionHolder)
                // 此处刚好衔接
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 3.3 获取该bean所依赖的所有bean,依次获取、注册
				String[] dependsOn = mbd.getDependsOn();
				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);
						getBean(dep);
					}
				}

				// 3.4 单例模式下的bean实例创建(最重要的方法,最终的bean实例创建在这)
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory() {
						@Override
						public Object getObject() throws BeansException {
							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);
				}

                // 3.5原型模式下的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);
				}

                // 3.6 按照给定模式来创建
				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() {
							@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);
					}
				}
			}
			...
		}
        ...
		return (T) bean;
	}

    总结:纵观以上代码,大致可分为两部分:

    1)已创建过该单例实例,则直接从singletonFactories中去取(singletonFactories是一个Map结构,key为name,value为ObjectFactory)

    2)没有创建过该实例,则重新创建,按照bean的scope类型来创建,prototype和singleton类型分别有不同的实现方式

 

    下面按照这两部分逐一介绍,先介绍没有创建该实例的情况

 

4.初次创建实例代码分析     1)根据beanName来获取BeanDefinition,并封装RootBeanDefinition(对应于3代码片段中的3.2小结)
		final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
		checkMergedBeanDefinition(mbd, beanName, args);

			    ...
        
                    
    // getMergedLocalBeanDefinition()
    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// 1.判断是否已经被创建过,如果已被创建过,则可以直接在mergedBeanDefinitions获取
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null) {
			return mbd;
		}
        // 2.新建
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));// 重要方法
	}


    // getBeanDefinition(),通过该方法来获取beanDefinitionMap对应的BeanDefinition
    // 具体实现在DefaultListableBeanFactory.getBeanDefinition(String beanName)方法
    public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
		BeanDefinition bd = this.beanDefinitionMap.get(beanName);//直接从beanDefinitionMap即可
		if (bd == null) {
			if (this.logger.isTraceEnabled()) {
				this.logger.trace("No bean named '" + beanName + "' found in " + this);
			}
			throw new NoSuchBeanDefinitionException(beanName);
		}
		return bd;
	}


    // getMergedBeanDefinition(),封装RootBeanDefinition
    protected RootBeanDefinition getMergedBeanDefinition(
			String beanName, BeanDefinition bd, BeanDefinition containingBd)
			throws BeanDefinitionStoreException {

		synchronized (this.mergedBeanDefinitions) {
			RootBeanDefinition mbd = null;

			// 1.先尝试从mergedBeanDefinitions获取,若已添加过该RootBeanDefinition,则会添加到mergedBeanDefinitions
			if (containingBd == null) {
				mbd = this.mergedBeanDefinitions.get(beanName);
			}
            
            // 2.mbd和bd.getParentName()都是null,
			if (mbd == null) {
				if (bd.getParentName() == null) {
					// Use copy of given root bean definition.
					if (bd instanceof RootBeanDefinition) {
						mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
					}
					else {
                        // 2.1直接走该逻辑,剩余代码直接略过
						mbd = new RootBeanDefinition(bd);
					}
				}
				...

				// 3.如果scope为空,则默认描述为单例模式
				if (!StringUtils.hasLength(mbd.getScope())) {
					mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
				}

				...
			}

			return mbd;
		}
	}    

   总结1):由上述过程可知,主要流程是:

    * 先从DefaultListableBeanFactory类的beanDefinitionMap中根据beanName获取对应的BeanDefinition

    * 将BeanDefinition封装一层,封装为RootBeanDefinition返回

 

    2)对该bean依赖的其他bean进行创建(对应于3代码片段中的3.3小结)
// 1.获取该bean所依赖的所有beanName	
String[] dependsOn = mbd.getDependsOn();
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 + "'");
        }
        // 2.将dep注册到dependentBeanMap中
        registerDependentBean(dep, beanName);
        // 3.循环getBean()方法,也就是重复当前bean的创建过程
        getBean(dep);
    }
}

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

  总结2):主要过程也就是获取当前bean依赖的所有bean,然后依次调用getBean()方法,重复当前bean的获取过程

 

    3)创建单例实例(对应于3代码片段中的3.3小结)重要方法
if (mbd.isSingleton()) {
    
    sharedInstance = getSingleton(beanName, new ObjectFactory() {
        @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);
}

    // getSingleton()
	public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
		synchronized (this.singletonObjects) {
            // 1.先从singletonObjects获取
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				...
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet();
				}
				try {
                    // 2.主要方法,会回调getSingleton()方法的getObject()方法
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				...
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                    // 3.将singletonObject放入singletonObjects
					addSingleton(beanName, singletonObject);
				}
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

   下面来查看最重要的回调方法getSingleton()方法中的 getObject()方法

    getObject()方法直接调用createBean()方法,这是一个抽象方法,默认实现类为AbstractAutowireCapableBeanFactory

	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// 1.获取beanName对应的class
		Class resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		...
		// 2.获取class对应的实例
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}


    // doCreateBean()
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            // 1.创建bean实例(重要方法)
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		...

		Object exposedObject = bean;
		try {
            // 2.初始化bean属性
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		...

		return exposedObject;
	}

    //createBeanInstance()
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		// 1.获取class
		Class beanClass = resolveBeanClass(mbd, beanName);

		...

		// 调用bean的无参构造函数
		return instantiateBean(beanName, mbd);
	}


    // instantiateBean()
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			...
			else {
                // 重要方法,获取bean实例
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		...
	}


    // instantiate()
	public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (bd.getMethodOverrides().isEmpty()) {
			Constructor constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
                    // 1.获取Class对象
					final Class clazz = bd.getBeanClass();
					...
				}
			}
            // 2.调用instantiateClass来获取实例,实际就是通过反射来获取
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}


    // 最终通过Constructor的反射来获取对应实例
	public static  T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			ReflectionUtils.makeAccessible(ctor);
            // 反射获取
			return ctor.newInstance(args);
		}
		...
	}

    总结3):可知,最终是通过bean的构造函数,来反射获取对应的实例的

 

总结4:纵观上述过程,再与之前的XMLBeanFactory构造方法结合起来,实际整个过程:

    1)从DefaultListableBeanFactory类的beanDefinitionMap中获取对应的BeanDefinition

    2)获取BeanDefinition中的class

    3)通过bean的构造函数,来反射获取该实例

 

5.再次获取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 + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}


	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
	}

    总结5:再次获取bean单例实例的逻辑就比较简单了,就是直接从singletonObjects中来获取对应的Object,由于之前创建的已经存在于singletonObjects,所以直接返回即可

 

    

参考:Spring源码深度解析(郝佳)

 

 

关注
打赏
1655041699
查看更多评论
立即登录/注册

微信扫码登录

0.3361s