Spring源码学习(一)DefaultListableBeanFactory

1、示例POJO类

用户类User,其中包含一个狗的引用

package org.springframework.cn.shu.edu.pojo;

public class User {
    String username;
    String password;
    Dog dog;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }
}

 

狗类

package org.springframework.cn.shu.edu.pojo;

public class Dog {
    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2、工程结构

Spring源码学习(一)DefaultListableBeanFactory_第1张图片

3、spring配置文件beans.xml



  
  
    
        
    

    
        
        
        
            
        
    



其中配置了一个Dog类的对象,一个User类的对象。

 

4、测试代码

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.cn.shu.edu.pojo.User;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class Test1 {
    public static void main(String[] args) {
        Resource res = new ClassPathResource("beans.xml");

        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
        reader.loadBeanDefinitions(res);

        User chenjie = factory.getBean("chenjie", User.class);
        System.out.println(chenjie.getUsername());

        User chenjie2 = factory.getBean("chenjie", User.class);
        System.out.println(chenjie2.getDog().getName());
    }
}

其中,首先定义了一个资源,指定从classpath下加载beans.xml文件,然后新建了一个DefaultListableBeanFactory的工厂对象,然后新建了一个XmlBeanDefinitionReader的Xml类定义读取器,接着使用该读取器加载bean定义。

随后便可以使用创建的工厂了,我们调用两次getBean。

首先观看输出:

Spring源码学习(一)DefaultListableBeanFactory_第2张图片

可以看到User类中的Dog类对象的引用两次都没有找到,而User类第一次没有找到,第二次找到了。我们将分析整个过程。

 

5、

Resource res = new ClassPathResource("beans.xml");

此句新建了一个ClassPathResource对象,用beans.xml作为参数。看看ClassPathResource的类图 

Spring源码学习(一)DefaultListableBeanFactory_第3张图片

Resource是Spring用来封装IO操作的类。在这里我们的BeanDefinition信息是以xml文件形式存在的。

这句代码首先调用了一个参数的构造函数,参数为bean定义的配置文件的路径

public ClassPathResource(String path) {
		this(path, (ClassLoader) null);
	}

可以看到它又调用了两个参数的构造函数,其中第二个参数为ClassLoader类型,这里由于此前没有指定ClassLoader是谁,因此设置为空。

再看看两个参数的构造函数

public ClassPathResource(String path, ClassLoader classLoader) {
		//判空
		Assert.notNull(path, "Path must not be null");
		//清洗路径
		String pathToUse = StringUtils.cleanPath(path);
		if (pathToUse.startsWith("/")) {
			pathToUse = pathToUse.substring(1);
		}
		this.path = pathToUse;
		//得到classLoader
		this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
	}

首先由于必须给定配置文件的路径,因此使用了断言来判空。

然后使用StringUtils工具类的cleanPath方法进行路径的整理。

public static String cleanPath(String path) {
		if (path == null) {
			return null;
		}
		String pathToUse = replace(path, WINDOWS_FOLDER_SEPARATOR, FOLDER_SEPARATOR);

		// Strip prefix from path to analyze, to not treat it as part of the
		// first path element. This is necessary to correctly parse paths like
		// "file:core/../core/io/Resource.class", where the ".." should just
		// strip the first "core" directory while keeping the "file:" prefix.
		int prefixIndex = pathToUse.indexOf(":");
		String prefix = "";
		if (prefixIndex != -1) {
			prefix = pathToUse.substring(0, prefixIndex + 1);
			pathToUse = pathToUse.substring(prefixIndex + 1);
		}
		if (pathToUse.startsWith(FOLDER_SEPARATOR)) {
			prefix = prefix + FOLDER_SEPARATOR;
			pathToUse = pathToUse.substring(1);
		}

		String[] pathArray = delimitedListToStringArray(pathToUse, FOLDER_SEPARATOR);
		List pathElements = new LinkedList();
		int tops = 0;

		for (int i = pathArray.length - 1; i >= 0; i--) {
			String element = pathArray[i];
			if (CURRENT_PATH.equals(element)) {
				// Points to current directory - drop it.
			}
			else if (TOP_PATH.equals(element)) {
				// Registering top path found.
				tops++;
			}
			else {
				if (tops > 0) {
					// Merging path element with element corresponding to top path.
					tops--;
				}
				else {
					// Normal path element found.
					pathElements.add(0, element);
				}
			}
		}

		// Remaining top paths need to be retained.
		for (int i = 0; i < tops; i++) {
			pathElements.add(0, TOP_PATH);
		}

		return prefix + collectionToDelimitedString(pathElements, FOLDER_SEPARATOR);
	}

整理完成以后,判断路径是否以/开头,如果是/开头,则表示是相对于classpath是根目录,所以用/后面的作为路径。

然后判断classloader是否为空,如果传入的不为空则使用之,如果为空,则调用ClassUtils.getDefaultClassLoader()来获取默认的ClassLoader,其方法如下。

public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back to system class loader...
		}
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			cl = ClassUtils.class.getClassLoader();
		}
		return cl;
	}

首先尝试得到当前线程的上下文的ClassLoader,如果获取失败会抛出异常,cl为空,则会获取ClassUtil类对象的ClassLoader并返回。

 

6、

DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

首先看看DefaultListableBeanFactory的类图。

可以看到是一个相对复杂的继承关系。

首先调用DefaultListableBeanFactory类的无参构造函数。

/**
	 * Create a new DefaultListableBeanFactory.
	 */
	public DefaultListableBeanFactory() {
		super();
		logger.info("初始化DefaultListableBeanFactory完成");
	}

可以看到什么都没有做,只是调用了父类的无参构造函数。我们来看看它的父类AbstractAutowireCapableBeanFactory的无参构造函数。

/**
	 * Create a new AbstractAutowireCapableBeanFactory.
	 */
	public AbstractAutowireCapableBeanFactory() {
		super();
		logger.info("初始化AbstractAutowireCapableBeanFactory()完成");
		ignoreDependencyInterface(BeanNameAware.class);
		ignoreDependencyInterface(BeanFactoryAware.class);
		ignoreDependencyInterface(BeanClassLoaderAware.class);
	}

可以看到其调用了父类的无参构造函数,接着调用了三次ignoreDependencyInterface方法,该方法其作用是指定自动装配(autowiring)的时候忽略的接口。这里我们先不做讨论。

https://www.jianshu.com/p/3c7e0608ff1f

我们来看看其调用的父类AbstractBeanFactory的无参构造函数

/**
	 * Create a new AbstractBeanFactory.
	 */
	public AbstractBeanFactory() {
		logger.info("初始化AbstractBeanFactory()完成");
	}

其中什么都没有做。到这里没有再显式地调用父类的构造函数,事实上,当我们再看AbstractBeanFactory的父类FactoryBeanRegistrySupport,FactoryBeanRegistrySupport的父类DefaultSingletonBeanRegistry,DefaultSingletonBeanRegistry的父类SimpleAliasRegistry的源码会发现其都没有写构造方法,也就是说其都是默认的空的无参构造函数。

 

7、

XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

这里新建一个XmlBeanDefinitionReader对象,并以此前创建的DefaultListableBeanFactory的对象factory作为参数。

public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
		super(registry);
		logger.info("初始化XmlBeanDefinitionReader()完成");
	}

再看其构造器,发现需要的参数只需要实现BeanDefinitionRegistry 接口即可,观察类图或者查看源码可知DefaultListableBeanFactory实现了BeanDefinitionRegistry接口

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
      implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {}

Spring源码学习(一)DefaultListableBeanFactory_第4张图片

该接口中有bean定义数量和bean定义名称两个属性,有注册bean定义、移除bean定义,得到bean定义、判断是否包含bean定义、bean名称是否在使用等方法。

XmlBeanDefinitionReader调用了父类的构造器如下:

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		// Determine ResourceLoader to use.
		if (this.registry instanceof ResourceLoader) {
			logger.info("this.registry instanceof ResourceLoader" );
			this.resourceLoader = (ResourceLoader) this.registry;
		}
		else {
			logger.info("this.registry is not instanceof ResourceLoader" );
			this.resourceLoader = new PathMatchingResourcePatternResolver();
		}
	}

首先进行必要的判空和赋值,然后判断传入的参数(这个registry对象参数肯定实现了BeanDefinitionRegistry ,但是否实现了ResourceLoader未知)是否实现了ResourceLoader。

我们这里传入的DefaultListableBeanFactory对象没有实现这个接口,因此在else里面,会新建一个PathMatchingResourcePatternResolver对象。

ResourceLoader提供 classpath下单资源文件的载入,而ResourcePatternResolver提供了多资源文件的载入。ResourcePatternResolver有一个实现类:PathMatchingResourcePatternResolver

我们这里新建了一个PathMatchingResourcePatternResolver对象。我们先不深入。

 

7、

reader.loadBeanDefinitions(res);

这里使用了XmlBeanDefinitionReader类的loadBeanDefinitions方法加载Resource类的对象res。

/**
	 * Load bean definitions from the specified XML file.
	 * @param resource the resource descriptor for the XML file
	 * @return the number of bean definitions found
	 * @throws BeanDefinitionStoreException in case of loading or parsing errors
	 */
	public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
		logger.info("进入loadBeanDefinitions(Resource resource)");
		return loadBeanDefinitions(new EncodedResource(resource));
	}

这里首先将resource进行encode,作用是进行编码。然后我们看看loadBeanDefinitions的具体实现。

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		logger.info("进入loadBeanDefinitions(EncodedResource encodedResource)");
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isInfoEnabled()) {
			logger.info("Loading XML bean definitions from " + encodedResource.getResource());
		}

		Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet(4);
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}

进行必要的判空后,首先使用

Set currentResources = this.resourcesCurrentlyBeingLoaded.get();
XmlBeanDefinitionReader内部维护了一个resourcesCurrentlyBeingLoaded变量,用于保存最近被加载的资源。
private final ThreadLocal> resourcesCurrentlyBeingLoaded =
      new NamedThreadLocal>("XML bean definition resources currently being loaded");

如果为空,则进行必要的初始化。

然后将传入的参数加入currentResources中,紧接着得到资源里面的输入流(public interface Resource extends InputStreamSource):

InputStream inputStream = encodedResource.getResource().getInputStream();

然后将输入流封装成了org.xml.sax库的InputSource对象,这里完成对xml的解析的加载过程。然后进行编码设置。

接着调用了doLoadBeanDefinitions(inputSource, encodedResource.getResource());方法。

做完以后关闭流,最后将传入的资源从最近被加载的资源中删除。

我们来看看doLoadBeanDefinitions方法的实现。

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
		try {
			int validationMode = getValidationModeForResource(resource);
			Document doc = this.documentLoader.loadDocument(
					inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware());
			return registerBeanDefinitions(doc, resource);
		}
//....
}
其中涉及validationMode验证模式,可以参考https://blog.csdn.net/nangongyanya/article/details/53887467

然后使用this.documentLoader.loadDocument方法来加载xml文档。documentLoader是DefaultDocumentLoader类的对象。

private DocumentLoader documentLoader = new DefaultDocumentLoader();

让我们来看看DefaultDocumentLoader类的loadDocument方法。

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isDebugEnabled()) {
			logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		return builder.parse(inputSource);
	}

它有几个参数,分别是输入源inputSource,实体解析器entityResolver,错误处理器errorHandler,XML验证模式validationMode,namespaceAware。最终落实到DocumentBuilder的parse方法。

接着调用registerBeanDefinitions(doc, resource);

	public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
		// Read document based on new BeanDefinitionDocumentReader SPI.
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
		int countBefore = getRegistry().getBeanDefinitionCount();
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

其中createBeanDefinitionDocumentReader方法主要新建了一个BeanDefinitionDocumentReader 接口的实现类DefaultBeanDefinitionDocumentReader然后调用其registerBeanDefinitions方法

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;

		logger.info("---->Loading bean definitions at " + DefaultBeanDefinitionDocumentReader.class.getSimpleName());
		Element root = doc.getDocumentElement();
		logger.info("--->root:" + root.getTagName());

		BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);

		preProcessXml(root);
		parseBeanDefinitions(root, delegate);
		postProcessXml(root);
	}

其中root代表了xml文档的根元素,可以增加打印语句看看:

从输出可以看到其根元素为

接着Bean定义解析代理类BeanDefinitionParserDelegate的对象,由它解析根元素中的内容,对于根元素前和跟元素后的内容,则由preProcessXml和postProcessXml两个方法完成,目前为空实现。我们来看看parseBeanDefinitions方法。

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}

首先判断是否是默认的命名空间,如果是,则执行parseDefaultElement,否则执行parseCustomElement。

我们这里是使用的默认的命名空间,因此接着调用getChildNodes方法获得下面的子节点,也就是

然后对于每个子节点,根据当前是否是默认命名空间来调用不同方法解析。

我们这里先只看parseDefaultElement。

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
			processBeanDefinition(ele, delegate);
		}
	}

这里分了3种情况,分别是节点标签名对应import alias 和bean的情况。

它们分别处理

我们这里只涉及bean的解析。来看看。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		/***
		 * BeanDefinitionHolder是BeanDefinition对象的封装类,封装了BeanDefinition,Bean的名字和别名。用它来完成向IoC容器注册。
		 * 得到这个BeanDefinition实际上就意味着获得了BeanDefinition,是通过BeanDefinitionParserDelegate对XML元素的信息按照
		 * Spring的Bean规则进行解析得到的
		 */
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 这里是向IoC容器注册解析得到的BeanDefinition的地方。
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// 发送注册事件
			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

Spring源码学习(一)DefaultListableBeanFactory_第5张图片BeanDefinitionHolder是BeanDefinition的封装。

而BeanDefinition可以看成是定义的抽象。

Spring源码学习(一)DefaultListableBeanFactory_第6张图片

可以看到其中包含关于类名、原型、延迟加载、单例、依赖的方法。

具体的加载过程由BeanDefinitionParserDelegate对XML元素的信息按照Spring的Bean规则进行解析得到的,入口是

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean){}

Spring源码学习(一)DefaultListableBeanFactory_第7张图片

Spring源码学习(一)DefaultListableBeanFactory_第8张图片

其中会调用parseBeanDefinitionElement方法。

public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, BeanDefinition containingBean) {
		logger.info("\tgo into parseBeanDefinitionElement of beanName :" + beanName);
		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
			logger.info("\tclass =" + className);
		}

		try {
			String parent = null;
			//如果元素有parent属性
			if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
				//得到parent节点
				parent = ele.getAttribute(PARENT_ATTRIBUTE);
			}
			//根据parent创建AbstractBeanDefinition
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);

			//解析bean定义
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			//为bean定义设置描述
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

			parseMetaElements(ele, bd);
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

			//解析构造器参数元素
			parseConstructorArgElements(ele, bd);
			//解析属性元素
			parsePropertyElements(ele, bd);
			parseQualifierElements(ele, bd);

			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));

			return bd;
		}
		catch (ClassNotFoundException ex) {
			error("Bean class [" + className + "] not found", ele, ex);
		}
		catch (NoClassDefFoundError err) {
			error("Class that bean class [" + className + "] depends on not found", ele, err);
		}
		catch (Throwable ex) {
			error("Unexpected failure during bean definition parsing", ele, ex);
		}
		finally {
			this.parseState.pop();
		}

		return null;
	}

其中createBeanDefinition创建一个BeanDefinition的实现GenericBeanDefinition。然后调用parseConstructorArgElements、parsePropertyElements等解析构造器参数,解析属性元素等。

createBeanDefinition中直接使用BeanDefinitionReaderUtils.createBeanDefinition创建bean。
public static AbstractBeanDefinition createBeanDefinition(
			String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {

		GenericBeanDefinition bd = new GenericBeanDefinition();
		bd.setParentName(parentName);
		if (className != null) {
			if (classLoader != null) {
				bd.setBeanClass(ClassUtils.forName(className, classLoader));
			}
			else {
				bd.setBeanClassName(className);
			}
		}
		return bd;
	}

其中使用了ClassUtils加载类的定义,然后为BeanDefinition设置了bean的class属性。

parsePropertyElements中循环调用了多次parsePropertyElement来处理每个property

Spring源码学习(一)DefaultListableBeanFactory_第9张图片

Spring源码学习(一)DefaultListableBeanFactory_第10张图片与XML中定义一致。

 

然后回到:DefaultBeanDefinitionDocumentReader

解析bean定义后,使用如下方法注册bean定义,这里的getReaderContext().getRegistry()就是最开始新建的工厂对象DefaultListableBeanFactory。

BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());

主要代码如下,即调用registerBeanDefinition方法。

Spring源码学习(一)DefaultListableBeanFactory_第11张图片

该方法主要是往一个并发HashMap中写入刚刚注册得到的bean定义

private final Map beanDefinitionMap = new ConcurrentHashMap();

由此,便将bean名字到bean定义的映射保存在了DefaultListableBeanFactory中。

8、

User chenjie = factory.getBean("chenjie", User.class);

这里调用了DefaultListableBeanFactory的getBean方法,但该方法是从父类AbstractBeanFactory继承而来。

public  T getBean(String name, Class requiredType) throws BeansException {
		logger.info("AbstractBeanFactory getBean,name=" + name + ",requiredType=" + requiredType);
		return doGetBean(name, requiredType, null, false);
	}

直接调用doGetBean

protected  T doGetBean(
			final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
		logger.info("AbstractBeanFactory doGetBean,name=" + name + ",requiredType=" + requiredType);

		final String beanName = transformedBeanName(name);

		logger.info("transformedBeanName, beanName=" + beanName);

		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		//先从缓存中去取,处理已经被创建过的单件模式的bean,对这种bean的请求不需要重复地创建
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			logger.info("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 + "'");
				}
			}

			/***
			 * 这里的getObjectForBeanInstance完成的是FactoryBean的相关处理,
			 * 以取得FactoryBean的生产结果,BeanFactory和FactoryBean的区别
			 * 会在这个过程中详细地分析
			 */
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			logger.info("sharedInstance == null || args != null");
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			/**
			 * 这里对IoC容器里的BeanDefinition是否存在进行检查,检查是否能在当前的BeanFactory中取到我们需要的bean。
			 * 如果在当前的工厂中取不到,则到双亲BeanFactory中去取;
			 * 如果当前的双亲工厂取不到,那就顺着双亲BeanFactory链一直向上查找
			 */
			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) {
				markBeanAsCreated(beanName);
			}

			//这里根据bean的名字取得BeanDefinition
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			/***
			 * 取当前bean的所有依赖bean,这样会触发getBean的递归调用,直至取到一个没有任何依赖的bean为止。
			 */
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					getBean(dependsOnBean);
					registerDependentBean(dependsOnBean, beanName);
				}
			}

			// Create bean instance.
			/***
			 * 这里创建Singleton bean的实例,通过调用crateBean方法,这里有个回调函数getObject,
			 * 会在getSingleton中调用ObjectFactory的createBean
			 */
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory() {
					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);
			}

			//这里是创建prototype 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 '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory() {
						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);
				}
			}
		}

		// Check if required type matches the type of the actual bean instance.
		/***
		 * 这里对创建出来的bean进行类型检查,如果没有问题,就返回这个新创建出来的bean,
		 * 这个bean已经是包含了依赖关系的bean
		 */
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			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());
			}
		}
		return (T) bean;
	}

总结:

你可能感兴趣的:(Java,Spring)