spring的Ioc实现

我们经常提到spring,就不得不说spring的IOC和AOP。今天我们先说一下spring的IOC。参考书籍:Spring技术内幕

不打算说太多概念性的东西,只是按我看书的理解主要说一下,以后可能有时间会专门在详细的说一下Ioc的实现。

Ioc(Inversion Of Control)控制反转

这里我们到底反转了什么?

       这里我们依赖对象的获取被反转了。以前我们都是由两个或多个类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象(它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么将导致代码高度耦合并且难以测试。

       在面向对象系统中,对象分封装了数据和对数据的处理,对象的依赖关系常常体现在对数据和方法的依赖上。这些依赖关系可以通过把对象的依赖注入交给框架或Ioc容器来完成,这种从具体对象手中交出控制的做法是非常有价值的。

       总结:就是以前我们需要控制对象的生成和对象之间依赖的处理,现在这些都交给Ioc容器来控制,我们现在只是需要用这些对象的实现向IOC容器要就行,不需要我们在自己去控制对象的生成和依赖关系的处理。

IOC容器的实现

      我们在研究Ioc容器时,可以看到最主要的两个实现,一个是实现BeanFactory接口的简单容器系列,这系列容器只实现了容器的基本功能;另一个是ApplicationContext应用上下文,它作为容器的高级形态而存在。

       如果我们把Ioc容器看成是一个水桶,BeanFactory就定义了可以作为水桶的基本功能,比如水桶必须可以装水,要有提手等。而除了基本功能,比如面对不同的厂家,在这个基础上设计了其他各种各样的水桶产品,比如是用塑料做的,还又添加了一个底座等功能。但是不管是什么水桶,都必须有一项基本功能,可以装水。对Spring的具体Ioc容器实现来说,它需要满足BeanFactory这个基本接口的定义,所以在spring的ioc容器实现中,BeanFactory是作为一个最基本的接口类出现的。

       在Ioc容器的接口和实现基础上,Spring通过定义BeanDefinition来管理基于spring的应用中的各种对象以及它们之间的相互依赖关系。对Ioc容器来说,BeanDefinition就是对依赖反转模式中管理的对象依赖关系的数据抽象,也是容器实现依赖反转功能的核心数据结构,依赖反转功能都是围绕对这个BeanDefinition的处理来完成的。这些BeanDefinition就像是容器里的水,有了这些基本数据,容器才能够发挥作用。

      在Spring代码中,BeanFactory只是一个接口类,并没有给出容器的具体实现。而比如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等可以看成容器附加了某种功能的具体实现,也就是具体的容器产品。

其中BeanFactory定义的操作:

public interface BeanFactory {
	public static final String FACTORY_BEAN_PREFIX = "&";

	public Object getBean(String var1) throws BeansException;  //通过名字获取bean

	public <T> T getBean(String var1, Class<T> var2) throws BeansException;

	public <T> T getBean(Class<T> var1) throws BeansException;

	public Object getBean(String var1, Object... var2) throws BeansException;

	public boolean containsBean(String var1); //判断容器是否包含指定的bean

	public boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;  //查询指定名字的bean是不是Singleton类型的bean

	public boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

	public boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException; //查询指定了名字的bean的class类型是否是特定的class类型

	public Class<?> getType(String var1) throws NoSuchBeanDefinitionException;//查询指定bean的class类型

	public String[] getAliases(String var1);//查询指定了名字的bean的所有别名,这些别名都是用户在BeanDefinition中定义的
}

      ApplicationContext是在BeanFactory提供的BeanFactory基础上,添加了一些BeanFactory不具备的新特性:

——  支持不同的信息源。ApplicationContext扩展了MessageSource接口。这些信息源的扩展功能可以支持国际化的实现。

——  访问资源。 这一特性体现在ResourceLoader和Resource的支持上,这样我们可以从不同地方得到Bean的定义资源。尤其是从不同的I/O途径得到Bean定义信息。ApplicationContext继承了DefaultResourceLoader的子类,因为DefaultResourceLoader是AbstractApplicationContext的基类。

——  支持应用事件。 继承了接口ApplicationEventPublisher,从而在上下文中引入了事件机制。这些事件和Bean的生命周期的结合为Bean的管理提供了便利。

Ioc容器的初始化过程

      Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动。这个启动包括BeanDefinition的Resource定位、载入和注册三个基本过程。在Spring中,Spring把这三个过程分开,并使用不同的模块来完成,如使用相应的ResourceLoader、BeanDefinitionReader等模块,使用这样的设计方式,可以让用户更加灵活地对三个过程进行剪裁或扩展。

       第一个过程是Resource定位过程。这个Resource定位指的是BeanDefinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDefinition的使用都提供了统一接口。对于这些BeanDefinition的存在形式,比如,在文件系统中的Bean定义信息可以使用FileSystemResource来进行抽象;在类路径中的Bean定义信息可以使用前面提到的ClassPathResource来使用,等。这个定位过程类似于容器寻找数据的过程,就像用水桶装水先要把水找到一样。

       第二个过程是BeanDefinition的载入。这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDefinition。这个BeanDefinition实际上就是POJO对象在Ioc容器中的抽象,通过这个BeanDefinition定义的数据结构,使Ioc容器能够方便地对POJO对象也就是Bean进行管理。

       第三个过程是向Ioc容器注册这些BeanDefinition的过程。这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的。这个注册过程把载入过程中解析得到的BeanDefinition向Ioc容器进行注册。其实是在Ioc容器内部将BeanDefinition注入到一个HashMap中去,Ioc容器就是通过这个HashMap来持有这些BeanDefinition数据的。

       这里注意的是:Ioc容器的初始化的过程,在这个过程中,一般不包含Bean依赖注入的实现。在Spring Ioc的设计中,Bean定义的载入和依赖注入是两个独立的过程。依赖注入一般发生在应用第一次通过getBean向容器索取Bean的时候。但有一个例外,在使用Ioc容器时有一个预实例化的配置,通过这个预实例化的配置(具体来说,可以通过为Bean定义信息中的lazyinit属性),用户可以对容器初始化过程做一个微小的控制,从而改变这个被设置了lazyinit属性的Bean的依赖注入的过程。举例来说,如果我们对某个Bean设置了lazyinit属性,那么这个Bean的依赖注入在Ioc容器初始化时就预先完成了,而不需要等到整个初始化完成以后,第一次使用getBean时才会触发。

BeanDifinition的Resource定位

       以ApplicationContext为例,因为在ApplicationContext中,spring已经为我们提供了一系列加载不同Resource的读取器的实现,例如FileSystemXmlApplicationContext、ClassPathXmlApplicationContext以及XmlWebApplicationContext等。我们可以从类的名字上面分析,可以知道他们可以提供哪些不同的Resource读入功能,比如FileSystemXmlApplicationContext可以从文件系统载入Resource,ClassPathXmlApplicationContext可以从Class Path载入Resource,XmlWebApplicationContext可以在Web容器中载入Resource等。

       我们下面以FileSystemXmlApplicationContext为例,分析这个ApplicationContext的实现。我们可以从源码中看到,这个FileSystemXmlApplicationContext已经通过继承AbstractApplicationContext具备了ResourceLoader读入以Resource定义的BeanDefinition的能力,因为AbstractApplicationContext的基类是DefaultResourceLoader。

     而我们现在需要关心的是这个FileSystemXmlApplicationContext在哪里定义了BeanDifinition的读入器BeanDefinitionReader,从而完成BeanDifinition信息的读入呢?我们需要进入FileSystemXmlApplicationContext的基类看一下AbstractRefreshableApplicationContext中看一下。

        我们需要重点看它的refershBeanFactory方法的实现,这个refreshBeanFactory被FileSytemXmlApplicationContext构造函数中的refresh调用。在这方法中,通过createBeanFactory构建了一个Ioc容器供ApplicationContext使用,而这个Ioc容器就是DefaultListableBeanFactory(ApplicationContext和XmlBeanFactory也是通过持有或扩展DefaultListableBeanFactory来获取最基本的Ioc容器的功能的)。同时,DefaultListableBeanFactory它启动了loadBeanDefinitions来载入BeanDefinition。从FileSystemXmlApplicationContext中可以看到,在初始化FileSystemXmlApplicationContext的过程中,通过Ioc容器的初始化的refresh来启动整个调用,使用的Ioc容器是DefaultListableBeanFactory。具体的资源载入在XmlBeanDefinitionReader读入BeanDefinition时完成,在XmlBeanDefinitionReader的基类AbstractBeanDefinitionReader中可以看到这个载入过程的具体实现。而载入过程的启动可以在AbstratctRefreshableApplicationContext的loadBeanDefinitions方法中看到。

protected final void refreshBeanFactory() throws BeansException {
	// 这里判断,如果已建立了BeanFactory,则销毁并关闭该BeanFactory
	if (hasBeanFactory()) {
		destroyBeans();
		closeBeanFactory();
	}
	// 这里是创建并设置持有的DefaultListableBeanFactory的地方同时调用
	// loadBeanDefinitions再载入BeanDefinition的信息
	try {
		DefaultListableBeanFactory beanFactory = createBeanFactory();
		beanFactory.setSerializationId(getId());
		customizeBeanFactory(beanFactory);
		loadBeanDefinitions(beanFactory);
		synchronized (this.beanFactoryMonitor) {
			this.beanFactory = beanFactory;
		}
	}
	catch (IOException ex) {
		throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
	}
}
/*
 * 这里就是在上下文创建DefaultListableBeanFactory的地方,而getinternalParentBeanFactory()
 * 的具体实现可以参看AbstractApplicationContext中的实现,会根据容器已有的双亲Ioc容器的信息来生成
 * DefaultListableBeanFactory的双亲Ioc容器
 */
protected DefaultListableBeanFactory createBeanFactory() {
	return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
//这里是使用BeanDefinitionReader载入Bean的地方,因为允许有多种载入的方式,
//虽然用的最多的是XML定义的形式,这里通过一个抽象函数把具体的实现委托给子类来完成
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
		throws BeansException, IOException;
//AbstractBeanDefinitionReader中实现的方法
public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {
	// 这里取得ResourceLoader,使用的是DefaultResourceLoader
	ResourceLoader resourceLoader = getResourceLoader();
	if (resourceLoader == null) {
		throw new BeanDefinitionStoreException(
				"Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");
	}

	// 这里对Resource的路径模式进行解析,比如我们设定的各种Ant格式的路劲定义,
	// 得到需要的Resource集合,这些Resource集合指向我们已经定义好的BeanDefinition信息,可以是多个文件
	if (resourceLoader instanceof ResourcePatternResolver) {
		// Resource pattern matching available.
		try {
			// 调用DefaultResourceLoaderdegetResource完成具体的Resource定位
			Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
			int loadCount = loadBeanDefinitions(resources);
			if (actualResources != null) {
				for (Resource resource : resources) {
					actualResources.add(resource);
				}
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");
			}
			return loadCount;
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"Could not resolve bean definition resource pattern [" + location + "]", ex);
		}
	}
	else {
		// Can only load single resources by absolute URL.
		// 调用DefaultResourceLoader的getResource完成具体的Resource定位
		Resource resource = resourceLoader.getResource(location);
		int loadCount = loadBeanDefinitions(resource);
		if (actualResources != null) {
			actualResources.add(resource);
		}
		if (logger.isDebugEnabled()) {
			logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
		}
		return loadCount;
	}
}
//DefaultResourceLoader中的实现
//对于具体的Resource具体过程,我们可以看看DefaultResourceLoader是怎样完成的
public Resource getResource(String location) {
	Assert.notNull(location, "Location must not be null");
	
	if (location.startsWith("/")) {
		return getResourceByPath(location);
	}
	// 这里处理带有classpath标识的Resource
	else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
		return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
	}
	else {
		try {
			// Try to parse the location as a URL...
			// 这里处理URL标识的Resource定位
			URL url = new URL(location);
			return new UrlResource(url);
		}
		catch (MalformedURLException ex) {
			// No URL -> resolve as resource path.
			// 如果既不是classpath,也不是URL标识的Resource定位,则把getResource
			// 的重任交给getResourceByPath,这个方法是一个protected方法,
			// 默认的实现是得到一个ClassPathContextResource,这个方法常常会用子类来实现
			return getResourceByPath(location);
		}
	}
}

      我们需要注意的是其中getResourceByPath会被子类FileSystemXmlApplicationContext实现,而这个方法返回是一个FileSystemResource对象,通过这个对象,spring就可以进行相关的I/O操作,完成BeanDefinition的定位。其实它实现的是对path进行解析,然后生成一个FileSystemResource对象并返回。

        到这里,我们就定位到了以FileSystem方式存在的Resource的定位实现。(水源找到了)

BeanDefinition的载入和解析

        在完成对BeanDefinition的Resource定位分析后,我们来分析载入的过程,对Ioc容器来说,这个载入过程,相当于把定义的BeanDefinition在Ioc容器中转化为一个spring内部表示的数据结构。Ioc容器对Bean的管理和依赖注入功能的实现,是通过对其持有的BeanDefinition进行各种相关的操作来完成的。这些BeanDefinition数据在Ioc容器中通过一个HashMap来保持和维护。

    对容器的启动来说,refresh是一个很重要的方法。该方法在AbstractApplicationContext类(它是FileSystemXmlApplicationContext的基类)中找到,它详细的描述了整个ApplicationContext的初始化过程,比如BeanFactory的更新,MessageSource和PostProcessor的注册等。

       我们需要进入AbstractApplicationContext的子类AbstractRefreshableApplicationContext的refreshBeanFactory()方法中,在这个方法中创建了BeanFactory。在创建Ioc容器前,如果已经有容器存在,那么需要把已有的容器销毁和关闭,保证该refresh以后使用的是新建立起来的Ioc容器。而建立好当前deIoc容器后,开始了对容器的初始化过程,如BeanDefinition的载入。

protected final void refreshBeanFactory() throws BeansException {
		if (hasBeanFactory()) { //判断,如果有,销毁已有的Ioc容器
			destroyBeans();
			closeBeanFactory();
		}
		try {     //创建Ioc容器,这里使用的是DefaultListableBeanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory); //启动对BeanDefinition的载入
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

而这个方法是一个抽象方法,我们需要进入AbstractRefreshableApplicationContext的子类AbstractXmlApplicationContext中的实现这个抽象方法中去。在这个loadBeanDefinitions中,初始化了读取器XmlBeanDefinitionReader,然后把这个读取器在Ioc容器中设置好,最后是启动读取器来完成BeanDefinition在Ioc容器中的载入。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// Create a new XmlBeanDefinitionReader for the given BeanFactory.
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// Configure the bean definition reader with this context's
	// resource loading environment.
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);//这里设置XmlBeanDefinitionReader
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	// Allow a subclass to provide custom initialization of the reader,
	// then proceed with actually loading the bean definitions.
	initBeanDefinitionReader(beanDefinitionReader);//启动bean定义信息的载入过程
	loadBeanDefinitions(beanDefinitionReader);
}

接着就是loadBeanDefinitions调用的地方,首先得到BeanDefinition信息的Resource定位,然后直接调用XmlBeanDefinitionReader来读取,具体的载入过程委托给BeanDefinitionReader完成的。

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
	//以Resource的方式获得配置文件的资源位置
	Resource[] configResources = getConfigResources();
	if (configResources != null) {
		reader.loadBeanDefinitions(configResources);
	}
	//以String的形式获得配置文件的位置
	String[] configLocations = getConfigLocations();
	if (configLocations != null) {
		reader.loadBeanDefinitions(configLocations);
	}
}	//以Resource的方式获得配置文件的资源位置
	Resource[] configResources = getConfigResources();
	if (configResources != null) {
		reader.loadBeanDefinitions(configResources);
	}
	//以String的形式获得配置文件的位置
	String[] configLocations = getConfigLocations();
	if (configLocations != null) {
		reader.loadBeanDefinitions(configLocations);
	}
}

通过上面的分析,我们知道,在初始化FileSystemXmlApplicationContext的过程中是通过调用Ioc容器的refresh来启动整个BeanDefinition的载入过程的,这个初始化是通过定义的XmlBeanDefinitionReader来完成的。同时我们也知道,实际使用的Ioc容器是DefaultListableBeanFactory,具体的Resource载入在XmlBeanDefinitionReader读入BeanDefinition时实现。在XmlBeanDefinitionReader的实现中可以看到,是在reader.loadBeanDefinitions中开始进行BeanDefinition的载入的,而这时XmlBeanDefinitionReader的父类AbstractBeanDefinitionReader已经为BeanDefinition的载入做好了准备。

public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
	/*
	 * 如果启动的Resource为空,则停止BeanDefinition的载入
	 * 然后启动载入BeanDefinition的过程,这个过程会遍历整个Resource集合所包含的BeanDefinition信息
	 */	
	Assert.notNull(resources, "Resource array must not be null");
	int counter = 0;
	for (Resource resource : resources) {
		counter += loadBeanDefinitions(resource);
	}
	return counter;
}

       在读取器中,需要得到代表XML文件的Resource,因为这个Resource对象封装了对XML文件的I/O操作,所以读取器可以在打开I/O流后得到XML文件对象。有了这个文件对象后,就可以按照spring的Bean定义规则来对这个XML的文档树进行解析了。

       BeanDefinition的载入分成两部分,首先通过调用XML的解析器得到document对象,但这些document对象并没有按照spring的Bean规则进行解析。在完成通用的XML解析以后,才是按照spring的Bean规则进行解析的地方,这个按照spring的Bean规则进行解析的过程是在documentReader中实现的。其中对BeanDefinition的处理结果由BeanDefinitionHolder对象来持有,这个BeanDefinitionHolder除了持有BeanDefinition对象外,还持有其他与BeanDefinition相关的信息,比如Bean 的名字、别名集合等。这个BeanDefinitionHolder的生成是通过对Document文档树的内容进行解析来完成的。而这个解析过程是由BeanDefinitionParserDelegate来实现(具体在processBeanDefinition方法中实现)的。

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
	BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
	if (bdHolder != null) {
		bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
		try {
			// Register the final decorated instance.
			BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
		}
		catch (BeanDefinitionStoreException ex) {
			getReaderContext().error("Failed to register bean definition with name '" +
					bdHolder.getBeanName() + "'", ele, ex);
		}
		// Send registration event.
		getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
	}
}

       具体的spring BeanDefinition的解析是在BeanDefinitionParserDelegate中完成的,这个类包含了对各种spring Bean定义规则的处理,如常见的对BeanDefinition定义的处理,如id、name等属性元素。把这些元素的值从XML文件相应的元素的属性中读取出来以后,设置到生成的BeanDefinitionHolder中去。

       我们以对一个property进行解析为例子。还是在类BeanDefinitionParserDelegate的代码中,一层一层地对BeanDefinition中的定义进行解释,比如从属性元素集合到具体的每一个属性元素,然后才是对具体的属性值的处理。根据解析结果,对这些属性值的处理会被封装成ProPerty Value对象并设置到BeanDefinition对象中去。

//这里对指定的Bean元素的property子元素集合进行解析
//遍历所有Bean元素下定义的property元素
public void parsePropertyElements(Element beanEle, BeanDefinition bd) {
	NodeList nl = beanEle.getChildNodes();
	for (int i = 0; i < nl.getLength(); i++) {
		Node node = nl.item(i);
		if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {
			//在判断是propert元素后对该property元素进行解析的过程
			parsePropertyElement((Element) node, bd);
		}
	}
}
//这里取得property元素的值,也许是一个list或其他
public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {
	String elementName = (propertyName != null) ?
					"<property> element for property '" + propertyName + "'" :
					"<constructor-arg> element";

	// Should only have one child element: ref, value, list, etc.
	NodeList nl = ele.getChildNodes();
	Element subElement = null;
	for (int i = 0; i < nl.getLength(); i++) {
		Node node = nl.item(i);
		if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&
				!nodeNameEquals(node, META_ELEMENT)) {
			// Child element is what we're looking for.
			if (subElement != null) {
				error(elementName + " must not contain more than one sub-element", ele);
			}
			else {
				subElement = (Element) node;
			}
		}
	}
	//这里判断property的属性,是ref还是value,不允许同时是ref和value
	boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
	boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
	if ((hasRefAttribute && hasValueAttribute) ||
			((hasRefAttribute || hasValueAttribute) && subElement != null)) {
		error(elementName +
				" is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);
	}

	//如果是ref,创建一个ref的数据对象RuntimeBeanReference,这个对象封装了ref的信息
	if (hasRefAttribute) {
		String refName = ele.getAttribute(REF_ATTRIBUTE);
		if (!StringUtils.hasText(refName)) {
			error(elementName + " contains empty 'ref' attribute", ele);
		}
		RuntimeBeanReference ref = new RuntimeBeanReference(refName);
		ref.setSource(extractSource(ele));
		return ref;
	}
	//如果是value,创建一个value的数据对象TypeedStringValue,这个对象封装了value的信息
	else if (hasValueAttribute) {
		TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
		valueHolder.setSource(extractSource(ele));
		return valueHolder;
	}
	//如果还有子元素,触发对子元素的解析
	else if (subElement != null) {
		return parsePropertySubElement(subElement, bd);
	}
	else {
		// Neither child element nor "ref" or "value" attribute found.
		error(elementName + " must specify a ref or value", ele);
		return null;
	}
}

       这里是对property子元素的解析过程,Array、List、Set、Map等各种元素都会在这里进行解析,生成对应的数据对象,比如ManagedList、ManagedArray、ManagedSet等。这些Managed类是Spring对具体的BeanDefinition的数据封装。

        下面看一下List这样的属性配置是怎样被解析的,依然是在BeanDefinitionParserDelegate中,返回的是一个List对象,这个List是spring定义的ManagedList,作为封装List这类配置定义的数据封装。

public List<Object> parseListElement(Element collectionEle, BeanDefinition bd) {
	String defaultElementType = collectionEle.getAttribute(VALUE_TYPE_ATTRIBUTE);
	NodeList nl = collectionEle.getChildNodes();
	ManagedList<Object> target = new ManagedList<Object>(nl.getLength());
	target.setSource(extractSource(collectionEle));
	target.setElementTypeName(defaultElementType);
	target.setMergeEnabled(parseMergeAttribute(collectionEle));
	//具体的List元素的解析过程
	parseCollectionElements(nl, target, bd, defaultElementType);
	return target;
}
protected void parseCollectionElements(
		NodeList elementNodes, Collection<Object> target, BeanDefinition bd, String defaultElementType) {

	//遍历所有元素结点,并判断其类型是否为Element
	for (int i = 0; i < elementNodes.getLength(); i++) {
		Node node = elementNodes.item(i);
		if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT)) {
			//加入到target中,target是一个ManagedList,同时触发对一层子元素的解析过程
			//这是一个递归调用
			target.add(parsePropertySubElement((Element) node, bd, defaultElementType));
		
		}
	}
}

       经过这样逐层的解析,我们在XML文件中定义的BeanDefinition就整个被载入到了Ioc容器中,并在容器中建立了数据映射,或者可以看成POJO对象在Ioc容器中的抽象,这些数据结构可以以AbstractBeanDefinition为入口,让Ioc容器执行索引、查询等操作。经过这些步骤,IOC容器大体上就完成了管理Bean对象的数据准备工作。但是重要的依赖注入这时实际上还没发生,现在,在Ioc容器BeanDefinition中存在的还只是一些静态配置信息。这时容器还没有完全起作用,要完全发挥容器的作用,还需完成数据向容器的注册。

BeanDefinitionz在Ioc容器中的注册

       前面已经分析过BeanDefinition在Ioc容器中载入和解析的过程。在这些动作完成以后,用户定义的BeanDefinition信息已经在Ioc容器内建立起了自己的数据结构以及相应的数据表示,但此时这些数据还不能供Ioc容器的使用,需要在Ioc容器中对这些BeanDefinition数据进行注册。这个注册为Ioc容器提供了更友好的使用方式,在DefaultListableBeanFactory中,是通过一个HashMap来持有载入的BeanDefinition的,这个HashMap的定义在DefaultListableBeanFactory中可以看到:

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

将解析得到的BeanDefinition向Ioc容器中的beanDefinitionMap注册的过程中是在载入BeanDefinition完成后进行的。

      在DefaultListableBeanFactory中实现了BeanDefinitionRegistry接口,这个接口的实现完成BeanDefinition向容器的注册。这个注册过程并不复杂,就是把解析得到的BeanDefinition设置到hashmap中去。遇到同名的BeanDefinition,进行处理的时候需要依据allowBeanDefinitionOverriding的配置来完成。

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
		throws BeanDefinitionStoreException {

	Assert.hasText(beanName, "Bean name must not be empty");
	Assert.notNull(beanDefinition, "BeanDefinition must not be null");

	if (beanDefinition instanceof AbstractBeanDefinition) {
		try {
			((AbstractBeanDefinition) beanDefinition).validate();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
					"Validation of bean definition failed", ex);
		}
	}

	//注册的过程需要synchronized,保证数据的一致性
	synchronized (this.beanDefinitionMap) {
		//这里检查是不是有相同名字的BeanDefinition已经在Ioc容器中注册了,
		//如果有相同名字的BeanDefinition,但又不允许覆盖,那么会抛出异常。
		BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);
		if (oldBeanDefinition != null) {
			if (!this.allowBeanDefinitionOverriding) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
						"': There is already [" + oldBeanDefinition + "] bound.");
			}
			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (this.logger.isWarnEnabled()) {
					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
							" with a framework-generated bean definition ': replacing [" +
							oldBeanDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else {
				if (this.logger.isInfoEnabled()) {
					this.logger.info("Overriding bean definition for bean '" + beanName +
							"': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
				}
			}
		}
		/*
		 * 这是正常注册BeanDefinition的过程,把Bean的名字存入到BeanDefinitionName的同时,
		 * 把beanName作为Map的key,把beanDefinition作为value存入到Ioc容器持有的beanDefinition中去
		 */
		else {
			this.beanDefinitionNames.add(beanName);
			this.frozenBeanDefinitionNames = null;
		}
		this.beanDefinitionMap.put(beanName, beanDefinition);
	}
	resetBeanDefinition(beanName);
}

       完成了BeanDefinition的注册,就完成了Ioc容器的初始化过程。此时,在使用的Ioc容器DefaultListableBeanFactory中已经建立了整个Bean的配置信息,而且这些BeanDefinition已经可以被容器使用了,他们都在beanDefinitionMap里被检索和使用。容器里的作用就是对这些信息进行处理和维护,这些信息是容器建立依赖反转的基础。

Ioc容器的依赖注入

       Ioc容器的初始化过程主要是完成在Ioc容器中建立BeanDefinition数据映射。在此过程中并没有看到Ioc容器对Bean依赖关系进行注入。我们接下来就要分析Ioc容器是怎样对Bean的依赖关系进行注入的。

       假设当前Ioc容器已经载入了用户定义的Bean信息,开始分析依赖注入的原理。首先,注意到依赖注入的过程是用户第一次向Ioc容器索要Bean时触发的,(也有例外,就是我们可以在BeanDefinition信息中通过lazy-init属性来让容器完成对Bean的预实例化,这个预实例化实际上也是一个完成依赖注入的过程,但他是在初始化的过程中完成的,后面会进行分析)。当用户向Ioc容器索要Bean时,在基本的Ioc容器接口BeanFactory中,有一个getBean的接口定义,这个接口的实现就是触发依赖注入发生的地方。我们需要从DefaultListableBeanFactory的基类AbstractBeanFactory入手去看看getBean的实现。

/*
 * 这里是对BeanFactory接口的实现,比如getBean接口方法
 * 这些getBean接口方法最终是调用doGetBean来实现的
 */
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
	return doGetBean(name, requiredType, null, false);
}

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

public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
	return doGetBean(name, requiredType, args, false);
}
//这里是实际取得Bean的地方,也是触发依赖注入发生的地方
protected <T> T doGetBean(
		final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
		throws BeansException {

	final String beanName = transformedBeanName(name);
	Object bean;

	//先从缓存中取得Bean,处理那些已经被创建过的单件模式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 + "'");
			}
		}
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		/*
		 * 这里对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);
		}

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

			// 获取当前Bean的所有依赖Bean,这样会触发getBean的递归调用,
			// 直到取到一个没有任何依赖的Bean为止
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (String dependsOnBean : dependsOn) {
					if (isDependent(beanName, dependsOnBean)) {
						throw new BeanCreationException("Circular depends-on relationship between '" +
								beanName + "' and '" + dependsOnBean + "'");
					}
					registerDependentBean(dependsOnBean, beanName);
					getBean(dependsOnBean);
				}
			}

			// 进入到createBean中进行详细分析
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
					@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);
			}

			// 这里是创建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<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;
		}
	}

	// 这里对创建的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;
}

       这个就是依赖注入的入口,在这里触发依赖注入,而依赖注入的发生是在容器中的BeanDefinition数据已经建立好的前提下进行的。“程序 = 数据 + 算法”,前面的BeanDefinition就是数据。

       getBean是依赖注入的起点,之后会调用createBean,在这个过程中,Bean对象会依据BeanDefinition定义的要求生成。在AbstractAutowireCapableBeanFactory中实现了createBean,createBean不但生成了需要的Bean,还对Bean初始化进行了处理,比如实现了在BeanDefinition中的init-method属性定义

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

	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	// 这里需要判断创建的Bean是否可以实例化,这个类是否可以通过类装载器来载入
	resolveBeanClass(mbd, beanName);

	// Prepare method overrides.
	try {
		mbd.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// 如果Bean配置了PostProceessor, 那么这里返回的是一个proxy
		Object bean = resolveBeforeInstantiation(beanName, mbd);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	// 这里是创建Bean的调用
	Object beanInstance = doCreateBean(beanName, mbd, args);
	if (logger.isDebugEnabled()) {
		logger.debug("Finished creating instance of bean '" + beanName + "'");
	}
	return beanInstance;
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
	// 这个BeanWrapper是用来持有创建出来的Bean对象的
	BeanWrapper instanceWrapper = null;
	// 如果是Singleton,先把缓存中的同名Bean清除
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	// 这里是创建Bean的地方,由createBeanInstance来完成
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
	Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			mbd.postProcessed = true;
		}
	}

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, new ObjectFactory<Object>() {
			@Override
			public Object getObject() throws BeansException {
				return getEarlyBeanReference(beanName, mbd, bean);
			}
		});
	}

	// 这里是对Bean的初始化,依赖注入往往在这里发生,这个exposedObject在初始化处理
	// 完成以后会返回作为依赖注入完成后的Bean
	Object exposedObject = bean;
	try {
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}

      在这里我们看到,与依赖关系特别密切的方法有createBeanInstance和populateBean。在createBeanInstance中生成了Bean所包含的java对象,这个对象的生成有很多种不同的方式,可以通过工厂方法生成,也可以通过容器的autowire特性生成,这些生成方式都是由相关的BeanDefinition来指定的。可以看到不同的生成方式对应的实现。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
	// 确认需要创建的Bean实例的类可以实例化
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	// 这里使用工厂方法对Bean进行实例化
	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	}

	if (mbd.getFactoryMethodName() != null)  {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			return instantiateBean(beanName, mbd);
		}
	}

	// 使用构造函数进行实例化
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// 使用默认的构造函数对Bean进行实例化
	return instantiateBean(beanName, mbd);
}
// 最常见的实例化过程instantiateBean
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
	// 使用默认的实例化策略对Bean进行实例化,默认的实例化策略是CglibSubclassingInstantiationStrategy
	// 也就是使用CGLIB来对Bean进行实例化。
	try {
		Object beanInstance;
		final BeanFactory parent = this;
		if (System.getSecurityManager() != null) {
			beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					return getInstantiationStrategy().instantiate(mbd, beanName, parent);
				}
			}, getAccessControlContext());
		}
		else {
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
		}
		BeanWrapper bw = new BeanWrapperImpl(beanInstance);
		initBeanWrapper(bw);
		return bw;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
	}
}

        在Ioc容器中,要了解怎样使用CGLIB来生成Bean对象,需要看一下SimpleInstantiationStratery。这个类是Spring用来生成Bean对象的默认类,它提供了两种实例化Java对象的方法,一种是通过BeanUtils,他使用了JVM的反射功能,一种是通过CGLIB生成。

public class SimpleInstantiationStrategy implements InstantiationStrategy {
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
	// Don't override the class with CGLIB if no overrides.
	if (beanDefinition.getMethodOverrides().isEmpty()) {
		// 这里取得指定的构造器或者生成对象的工厂方法来对Bean进行实例化。
		Constructor<?> constructorToUse;
		synchronized (beanDefinition.constructorArgumentLock) {
			constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
			if (constructorToUse == null) {
				final Class<?> clazz = beanDefinition.getBeanClass();
				if (clazz.isInterface()) {
					throw new BeanInstantiationException(clazz, "Specified class is an interface");
				}
				try {
					if (System.getSecurityManager() != null) {
						constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
							@Override
							public Constructor<?> run() throws Exception {
								return clazz.getDeclaredConstructor((Class[]) null);
							}
						});
					}
					else {
						constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
					}
					beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
				}
				catch (Exception ex) {
					throw new BeanInstantiationException(clazz, "No default constructor found", ex);
				}
			}
		}
		// 通过BeanUtils进行实例化,这个Beanutils的实例化通过Constructor来实例化Bean
		// 在BeanUtils中可以看到具体的调用ctor.newInstance(args)
		return BeanUtils.instantiateClass(constructorToUse);
	}
	else {
		// Must generate CGLIB subclass.
		// 使用CGLIB来实例化对象
		return instantiateWithMethodInjection(beanDefinition, beanName, owner);
	}
}
}

       到这里分析了实例化Bean对象的整个过程。在Bean对象生成以后,怎样把这些Bean的依赖关系设置好,完成整个依赖注入过程,这些依赖关系处理的依据就是已经解析得到的BeanDefinition。详细解释这个过程,我们需要populateBean方法,这个方法在AbstractAutowireCapableBeanFactory中的实现代码。

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
	/*
	 * 这里取得在Beandefinition中设置的property值,这些property来自对BeanDefinition的解析
	 * 具体的解析过程可以参看对载入和解析BeanDefinition的分析
	 */
	PropertyValues pvs = mbd.getPropertyValues();

	if (bw == null) {
		if (!pvs.isEmpty()) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
		}
		else {
			// Skip property population phase for null instance.
			return;
		}
	}

	// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
	// state of the bean before properties are set. This can be used, for example,
	// to support styles of field injection.
	boolean continueWithPropertyPopulation = true;

	
	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					continueWithPropertyPopulation = false;
					break;
				}
			}
		}
	}

	if (!continueWithPropertyPopulation) {
		return;
	}

	// 开始进行依赖注入过程,先处理autowire的注入
	if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
			mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
		MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

		// Add property values based on autowire by name if applicable.
		// 这里是对autowire注入的处理,可以根据Bean的名字或者类型
		// 来完成Bean的autowire
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
			autowireByName(beanName, mbd, bw, newPvs);
		}

		// Add property values based on autowire by type if applicable.
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			autowireByType(beanName, mbd, bw, newPvs);
		}

		pvs = newPvs;
	}

	boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
	boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

	if (hasInstAwareBpps || needsDepCheck) {
		PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
		if (hasInstAwareBpps) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvs == null) {
						return;
					}
				}
			}
		}
		if (needsDepCheck) {
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
	}

	// 对属性进行注入
	applyPropertyValues(beanName, mbd, bw, pvs);
}

// 通过applyPropertyValues了解具体的对属性进行解析然后注入的过程
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	if (pvs == null || pvs.isEmpty()) {
		return;
	}

	MutablePropertyValues mpvs = null;
	List<PropertyValue> original;

	if (System.getSecurityManager() != null) {
		if (bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}
	}

	if (pvs instanceof MutablePropertyValues) {
		mpvs = (MutablePropertyValues) pvs;
		if (mpvs.isConverted()) {
			// Shortcut: use the pre-converted values as-is.
			try {
				bw.setPropertyValues(mpvs);
				return;
			}
			catch (BeansException ex) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Error setting property values", ex);
			}
		}
		original = mpvs.getPropertyValueList();
	}
	else {
		original = Arrays.asList(pvs.getPropertyValues());
	}

	TypeConverter converter = getCustomTypeConverter();
	if (converter == null) {
		converter = bw;
	}
	// 注意这个BeanDefinitionValueResolve对BeanDefinition的解析
	// 是在这个valueResolver中完成的
	BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

	
	// Create a deep copy, resolving any references for values.
	// 这里为解析值创建一个副本、副本的数据将会被载入到Bean中
	List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
	boolean resolveNecessary = false;
	for (PropertyValue pv : original) {
		if (pv.isConverted()) {
			deepCopy.add(pv);
		}
		else {
			String propertyName = pv.getName();
			Object originalValue = pv.getValue();
			Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
			Object convertedValue = resolvedValue;
			boolean convertible = bw.isWritableProperty(propertyName) &&
					!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
			if (convertible) {
				convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
			}
			// Possibly store converted value in merged bean definition,
			// in order to avoid re-conversion for every created bean instance.
			if (resolvedValue == originalValue) {
				if (convertible) {
					pv.setConvertedValue(convertedValue);
				}
				deepCopy.add(pv);
			}
			else if (convertible && originalValue instanceof TypedStringValue &&
					!((TypedStringValue) originalValue).isDynamic() &&
					!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
				pv.setConvertedValue(convertedValue);
				deepCopy.add(pv);
			}
			else {
				resolveNecessary = true;
				deepCopy.add(new PropertyValue(pv, convertedValue));
			}
		}
	}
	if (mpvs != null && !resolveNecessary) {
		mpvs.setConverted();
	}

	// Set our (possibly massaged) deep copy.
	 // 这里是依赖注入发生的地方,会在BeanWrapperImpl中完成
	try {
		bw.setPropertyValues(new MutablePropertyValues(deepCopy));
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Error setting property values", ex);
	}
}

     这里通过使用BeanDefinitionResolver来对BeanDefinition进行解析,然后注入到property中。下面到BeanDefinitionValueResolver中去看一下解析过程的体现,以对Bean reference进行解析为例,

private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	try {
		// 从RuntimeBeanDefinitionReference取得reference的名字,这个RuntimeBeanReference是在
		// 载入BeanDefinition时根据配置生成的
		String refName = ref.getBeanName();
		refName = String.valueOf(evaluate(refName));
		// 如果ref是在双亲Ioc容器中,那就到双亲Ioc容器中获取
		if (ref.isToParent()) {
			if (this.beanFactory.getParentBeanFactory() == null) {
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Can't resolve reference to bean '" + refName +
						"' in parent factory: no parent factory available");
			}
			return this.beanFactory.getParentBeanFactory().getBean(refName);
		}
		// 在当前Ioc容器中去获取Bean,这里会触发一个getBean的过程,如果依赖注入没有发生,
		// 这里会触发相应的依赖注入的发生
		else {
			Object bean = this.beanFactory.getBean(refName);
			this.beanFactory.registerDependentBean(refName, this.beanName);
			return bean;
		}
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				this.beanDefinition.getResourceDescription(), this.beanName,
				"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
	}
}
// 下面看一下对其他类型的属性进行注入的例子,比如array和list
private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
	Object resolved = Array.newInstance(elementType, ml.size());
	for (int i = 0; i < ml.size(); i++) {
		Array.set(resolved, i,
				resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
	}
	return resolved;
}

// 对于每一个在List中的元素,都会依次进行解析
private List<?> resolveManagedList(Object argName, List<?> ml) {
	List<Object> resolved = new ArrayList<Object>(ml.size());
	for (int i = 0; i < ml.size(); i++) {
		resolved.add(
				resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
	}
	return resolved;
}

         这两种属性的注入都调用了resolveValueIfNecessary,这个方法包含了所有对注入类型的处理。

public Object resolveValueIfNecessary(Object argName, Object value) {
	// We must check each value to see whether it requires a runtime reference
	// to another bean to be resolved.
	// 这里对RuntimeBeanReference进行解析,RuntimeBeanReference是在
	// 对BeanDefinition进行解析时生成的数据对象
	if (value instanceof RuntimeBeanReference) {
		RuntimeBeanReference ref = (RuntimeBeanReference) value;
		return resolveReference(argName, ref);
	}
	else if (value instanceof RuntimeBeanNameReference) {
		String refName = ((RuntimeBeanNameReference) value).getBeanName();
		refName = String.valueOf(evaluate(refName));
		if (!this.beanFactory.containsBean(refName)) {
			throw new BeanDefinitionStoreException(
					"Invalid bean name '" + refName + "' in bean reference for " + argName);
		}
		return refName;
	}
	else if (value instanceof BeanDefinitionHolder) {
		// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
		BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
		return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
	}
	else if (value instanceof BeanDefinition) {
		// Resolve plain BeanDefinition, without contained name: use dummy name.
		BeanDefinition bd = (BeanDefinition) value;
		String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
				ObjectUtils.getIdentityHexString(bd);
		return resolveInnerBean(argName, innerBeanName, bd);
	}
	// 这里对ManageArray进行解析
	else if (value instanceof ManagedArray) {
		// May need to resolve contained runtime references.
		ManagedArray array = (ManagedArray) value;
		Class<?> elementType = array.resolvedElementType;
		if (elementType == null) {
			String elementTypeName = array.getElementTypeName();
			if (StringUtils.hasText(elementTypeName)) {
				try {
					elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
					array.resolvedElementType = elementType;
				}
				catch (Throwable ex) {
					// Improve the message by showing the context.
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Error resolving array type for " + argName, ex);
				}
			}
			else {
				elementType = Object.class;
			}
		}
		return resolveManagedArray(argName, (List<?>) value, elementType);
	}
	// 这里对ManageList进行解析
	else if (value instanceof ManagedList) {
		// May need to resolve contained runtime references.
		return resolveManagedList(argName, (List<?>) value);
	}
	// 这里对ManageSet进行解析
	else if (value instanceof ManagedSet) {
		// May need to resolve contained runtime references.
		return resolveManagedSet(argName, (Set<?>) value);
	}
	// 这里对ManageMap进行解析
	else if (value instanceof ManagedMap) {
		// May need to resolve contained runtime references.
		return resolveManagedMap(argName, (Map<?, ?>) value);
	}
	// 这里对ManageProperties进行解析
	else if (value instanceof ManagedProperties) {
		Properties original = (Properties) value;
		Properties copy = new Properties();
		for (Map.Entry<Object, Object> propEntry : original.entrySet()) {
			Object propKey = propEntry.getKey();
			Object propValue = propEntry.getValue();
			if (propKey instanceof TypedStringValue) {
				propKey = evaluate((TypedStringValue) propKey);
			}
			if (propValue instanceof TypedStringValue) {
				propValue = evaluate((TypedStringValue) propValue);
			}
			copy.put(propKey, propValue);
		}
		return copy;
	}
	// 这里对TypedStringVlues进行解析
	else if (value instanceof TypedStringValue) {
		// Convert value to target type here.
		TypedStringValue typedStringValue = (TypedStringValue) value;
		Object valueObject = evaluate(typedStringValue);
		try {
			Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
			if (resolvedTargetType != null) {
				return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
			}
			else {
				return valueObject;
			}
		}
		catch (Throwable ex) {
			// Improve the message by showing the context.
			throw new BeanCreationException(
					this.beanDefinition.getResourceDescription(), this.beanName,
					"Error converting typed String value for " + argName, ex);
		}
	}
	else {
		return evaluate(value);
	}
}
// 对RuntimeBeanReference类型的注入在resolveReference中
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	try {
		// 从RuntimeBeanReference取得reference的名字,这个RuntimeBeanReference是在
		// 载入BeanDefinition时根据配置生成的
		String refName = ref.getBeanName();
		refName = String.valueOf(evaluate(refName));
		// 如果ref是在双亲Ioc容器中,那就到双亲Ioc容器中去获取
		if (ref.isToParent()) {
			if (this.beanFactory.getParentBeanFactory() == null) {
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(), this.beanName,
						"Can't resolve reference to bean '" + refName +
						"' in parent factory: no parent factory available");
			}
			return this.beanFactory.getParentBeanFactory().getBean(refName);
		}
		// 在当前Ioc容器中取得Bean,这里会触发一个getBean的过程,如果依赖注入没有发生,	
		// 这里会触发相应的依赖注入的发生
		else {
			Object bean = this.beanFactory.getBean(refName);
			this.beanFactory.registerDependentBean(refName, this.beanName);
			return bean;
		}
	}
	catch (BeansException ex) {
		throw new BeanCreationException(
				this.beanDefinition.getResourceDescription(), this.beanName,
				"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
	}
}
// 对manageList的处理过程在resolveManagedList中
private List<?> resolveManagedList(Object argName, List<?> ml) {
	List<Object> resolved = new ArrayList<Object>(ml.size());
	for (int i = 0; i < ml.size(); i++) {
		// 通过递归的方式,对List的元素进行解析
		resolved.add(
				resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
	}
	return resolved;
}

        在完成这个解析过程后,已经为依赖注入准备好了条件,这是真正把Bean对象设置到它所依赖的另一个Bean的属性中去的地方,其中处理的属性是各种各样的。依赖注入的发生是在BeanWrapper的setProperty Values中实现的,具体的完成却是在BeanWrapper的子类BeanWrapperImpl中实现的。

private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
	String propertyName = tokens.canonicalName;
	String actualName = tokens.actualName;

	if (tokens.keys != null) {
		// Apply indexes and map keys: fetch value for all keys but the last one.
		// 设置tokens的索引和keys
		PropertyTokenHolder getterTokens = new PropertyTokenHolder();
		getterTokens.canonicalName = tokens.canonicalName;
		getterTokens.actualName = tokens.actualName;
		getterTokens.keys = new String[tokens.keys.length - 1];
		System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);
		Object propValue;
		// getPropertyValue取得Bean中队注入对象的引用,比如Array、List、Map、Set等
		try {
			propValue = getPropertyValue(getterTokens);
		}
		catch (NotReadablePropertyException ex) {
			throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName,
					"Cannot access indexed value in property referenced " +
					"in indexed property path '" + propertyName + "'", ex);
		}
		// Set value for last key.
		String key = tokens.keys[tokens.keys.length - 1];
		if (propValue == null) {
			// null map value case
			if (this.autoGrowNestedPaths) {
				// TODO: cleanup, this is pretty hacky
				int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
				getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
				propValue = setDefaultValue(getterTokens);
			}
			else {
				throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + propertyName,
						"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "': returned null");
			}
		}
		// 这里对Array进行注入
		if (propValue.getClass().isArray()) {
			PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
			Class<?> requiredType = propValue.getClass().getComponentType();
			int arrayIndex = Integer.parseInt(key);
			Object oldValue = null;
			try {
				if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
					oldValue = Array.get(propValue, arrayIndex);
				}
				Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
						requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
				Array.set(propValue, arrayIndex, convertedValue);
			}
			catch (IndexOutOfBoundsException ex) {
				throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
						"Invalid array index in property path '" + propertyName + "'", ex);
			}
		}
		// 这里对List进行注入
		else if (propValue instanceof List) {
			PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
			Class<?> requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
					pd.getReadMethod(), tokens.keys.length);
			List<Object> list = (List<Object>) propValue;
			int index = Integer.parseInt(key);
			Object oldValue = null;
			if (isExtractOldValueForEditor() && index < list.size()) {
				oldValue = list.get(index);
			}
			Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
					requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
			int size = list.size();
			if (index >= size && index < this.autoGrowCollectionLimit) {
				for (int i = size; i < index; i++) {
					try {
						list.add(null);
					}
					catch (NullPointerException ex) {
						throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
								"Cannot set element with index " + index + " in List of size " +
								size + ", accessed using property path '" + propertyName +
								"': List does not support filling up gaps with null elements");
					}
				}
				list.add(convertedValue);
			}
			else {
				try {
					list.set(index, convertedValue);
				}
				catch (IndexOutOfBoundsException ex) {
					throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
							"Invalid list index in property path '" + propertyName + "'", ex);
				}
			}
		}
		// 这里对Map进行注入
		else if (propValue instanceof Map) {
			PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
			Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
					pd.getReadMethod(), tokens.keys.length);
			Class<?> mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
					pd.getReadMethod(), tokens.keys.length);
			Map<Object, Object> map = (Map<Object, Object>) propValue;
			// IMPORTANT: Do not pass full property name in here - property editors
			// must not kick in for map keys but rather only for map values.
			TypeDescriptor typeDescriptor = (mapKeyType != null ?
					TypeDescriptor.valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class));
			Object convertedMapKey = convertIfNecessary(null, null, key, mapKeyType, typeDescriptor);
			Object oldValue = null;
			if (isExtractOldValueForEditor()) {
				oldValue = map.get(convertedMapKey);
			}
			// Pass full property name and old value in here, since we want full
			// conversion ability for map values.
			Object convertedMapValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
					mapValueType, TypeDescriptor.nested(property(pd), tokens.keys.length));
			map.put(convertedMapKey, convertedMapValue);
		}
		else {
			throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
					"Property referenced in indexed property path '" + propertyName +
					"' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
		}
	}

	//这里对非集合类的域进行注入
	else {
		PropertyDescriptor pd = pv.resolvedDescriptor;
		if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
			pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
			if (pd == null || pd.getWriteMethod() == null) {
				if (pv.isOptional()) {
					logger.debug("Ignoring optional value for property '" + actualName +
							"' - property not found on bean class [" + getRootClass().getName() + "]");
					return;
				}
				else {
					PropertyMatches matches = PropertyMatches.forProperty(propertyName, getRootClass());
					throw new NotWritablePropertyException(
							getRootClass(), this.nestedPath + propertyName,
							matches.buildErrorMessage(), matches.getPossibleMatches());
				}
			}
			pv.getOriginalPropertyValue().resolvedDescriptor = pd;
		}

		Object oldValue = null;
		try {
			Object originalValue = pv.getValue();
			Object valueToApply = originalValue;
			if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
				if (pv.isConverted()) {
					valueToApply = pv.getConvertedValue();
				}
				else {
					if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
						final Method readMethod = pd.getReadMethod();
						if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
								!readMethod.isAccessible()) {
							if (System.getSecurityManager()!= null) {
								AccessController.doPrivileged(new PrivilegedAction<Object>() {
									@Override
									public Object run() {
										readMethod.setAccessible(true);
										return null;
									}
								});
							}
							else {
								readMethod.setAccessible(true);
							}
						}
						try {
							if (System.getSecurityManager() != null) {
								oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
									@Override
									public Object run() throws Exception {
										return readMethod.invoke(object);
									}
								}, acc);
							}
							else {
								oldValue = readMethod.invoke(object);
							}
						}
						catch (Exception ex) {
							if (ex instanceof PrivilegedActionException) {
								ex = ((PrivilegedActionException) ex).getException();
							}
							if (logger.isDebugEnabled()) {
								logger.debug("Could not read previous value of property '" +
										this.nestedPath + propertyName + "'", ex);
							}
						}
					}
					valueToApply = convertForProperty(
							propertyName, oldValue, originalValue, new TypeDescriptor(property(pd)));
				}
				pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
			}
			// 这里取得注入属性的set方法,通过反射机制,把对象注入进去
			final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?
					((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :
					pd.getWriteMethod());
			if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
				if (System.getSecurityManager()!= null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							writeMethod.setAccessible(true);
							return null;
						}
					});
				}
				else {
					writeMethod.setAccessible(true);
				}
			}
			final Object value = valueToApply;
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						@Override
						public Object run() throws Exception {
							writeMethod.invoke(object, value);
							return null;
						}
					}, acc);
				}
				catch (PrivilegedActionException ex) {
					throw ex.getException();
				}
			}
			else {
				writeMethod.invoke(this.object, value);
			}
		}
		catch (TypeMismatchException ex) {
			throw ex;
		}
		catch (InvocationTargetException ex) {
			PropertyChangeEvent propertyChangeEvent =
					new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
			if (ex.getTargetException() instanceof ClassCastException) {
				throw new TypeMismatchException(propertyChangeEvent, pd.getPropertyType(), ex.getTargetException());
			}
			else {
				throw new MethodInvocationException(propertyChangeEvent, ex.getTargetException());
			}
		}
		catch (Exception ex) {
			PropertyChangeEvent pce =
					new PropertyChangeEvent(this.rootObject, this.nestedPath + propertyName, oldValue, pv.getValue());
			throw new MethodInvocationException(pce, ex);
		}
	}
}

       这样就完成了对各种Bean属性的依赖注入过程。在Bean的创建和对象依赖注入的过程中,需要依据BeanDefinition中的信息来递归地完成依赖注入。从上面的几个递归过程中可以看到,这些递归都是以getBean为入口的。一个递归是在上下文体系中查找需要的Bean和创建Bean 的递归调用;另一个递归是在依赖注入时,通过递归调用容器的getBean方法,得到当前Bean的依赖Bean,同时也触发对依赖Bean的创建和注入,一层一层地完成Bean的创建和注入,直到最后完成当前Bean的创建。有了这个顶层Bean的创建和对它的属性依赖注入的完成,意味着和当前Bean相关的整个依赖链的注入也完成了。

       在Bean 创建和依赖注入完成以后,在Ioc容器中建立起一系列依靠依赖关系联系起来的Bean,这个Bean已经不是简单的Java对象了。该Bean系列以及Bean之间的依赖关系建立完成以后,通过Ioc容器的相关接口方法,就可以非常方便地供上层应用使用了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值