Spring IOC理解

一、概念的理解

        要知道ApplicationContext首先要知道BeanFactory。BeanFactory就是生产bean的工厂,负责生产和管理各个bean实例。而ApplicationContext就是继承自BeanFactory,有个继承结构图画的糙,但是表达很明确:

 1.1 ApplicationContext

首先要对ApplicationContext进行一定了解:

  • 其主要解读为应用程序上下文
    • 对Java程序来说,在运行测试类之前,首先要先加载程序的上下文,即进行加载程序需要的“运行环境”的配置
    • 对Spring来说,如果要运行TestService这个Bean,就必须首先进行Spring环境配置,以此来配置TestService的上下文环境。
  • 还有很重要的一点,源码解读过后,通过对ApplicationContext的理解逐渐加深,可以看出:
    • ApplicationContext虽然继承自BeanFactory,但是它的执行过程中始终在内部实例化了一个BeanFactory,即一个DefaultListableBeanFactory,之后与BeanFactory相关的操作,都是通过该实例处理。
    • 对该部分详细内容见下方3.1最后的分析

1.2 对Bean的理解

一直在说BeanFactory就是一个Bean容器,那如何理解Bean呢?

实际上,在代码层面,对开发者自己定义的bean,会被Spring转化为一个个BeanDefinition实例并存储在BeanFactory中。BeanDefinition的实例可以保存各种Bean信息。

二、表层源码解读

先进行一个总览:

本次源码解读从ClassPathXmlApplicationContext开始,首先来看一下源码:

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
	@Nullable
	private Resource[] configResources;

	public ClassPathXmlApplicationContext() {
	}

    // 可以传入一个父类ApplicationContext,进行父子关系的配置
	public ClassPathXmlApplicationContext(ApplicationContext parent) {
		super(parent);
	}

	public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

	public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
		this(configLocations, true, null);
	}

	public ClassPathXmlApplicationContext(String[] configLocations, @Nullable ApplicationContext parent)
			throws BeansException {

		this(configLocations, true, parent);
	}

	public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {
		this(configLocations, refresh, null);
	}

    // 使用给定的父类创建一个新的ClassPathXmlApplicationContext,从给定的XML文件加载定义
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
        // 源码见源码块一
		setConfigLocations(configLocations);
        // 调用refresh()方法重建 ApplicationContext,源码见源码块二:
		if (refresh) {
			refresh();
		}
	}

	public ClassPathXmlApplicationContext(String path, Class<?> clazz) throws BeansException {
		this(new String[] {path}, clazz);
	}

	public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz) throws BeansException {
		this(paths, clazz, null);
	}

	public ClassPathXmlApplicationContext(String[] paths, Class<?> clazz, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		Assert.notNull(paths, "Path array must not be null");
		Assert.notNull(clazz, "Class argument must not be null");
		this.configResources = new Resource[paths.length];
		for (int i = 0; i < paths.length; i++) {
			this.configResources[i] = new ClassPathResource(paths[i], clazz);
		}
		refresh();
	}

	@Override
	@Nullable
	protected Resource[] getConfigResources() {
		return this.configResources;
	}
}

源码块一:setConfigLocations方法源码

    // 传入多个配置路径,然后存储在配置文件数组中
	public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

源码块二:refresh方法源码

    // 当已经创建了ApplicationContext后,可以通过refresh方法将原来的ApplicationContext销毁,然后重新执行初始化操作
	@Override
	public void refresh() throws BeansException, IllegalStateException {
        // 给refresh操作加锁
		synchronized (this.startupShutdownMonitor) {
            // 为刷新上下文进行准备工作,设置它的启动日期、活动标志(即配置“已启动”状态),以及执行任何属性源的初始化。
			prepareRefresh();

            /**
			* 源码注释:告诉子类刷新内部bean工厂
            *    方法中调用refreshBeanFactory()方法进行Bean工厂的刷新,其专用于在所有初始化操作之前调用
            *    然后调用getBeanFactory()方法来返回创建的新Bean工厂或者返回一个已经存在的BeanFactory
            * 总:这步的主要作用是为了解析配置文件,解析为一个个Bean,然后注册到BeanFactory中
            * 注意:这一步并没有进行Bean的初始化,只是提取配置信息,将其保存至注册中心
            */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            /** 
            * 源码注释:准备在上下文中使用的Bean工厂
            * 该方法用于配置Bean工厂的一些内容,例如配置BeanFactory的ClassLoader,添加post-processors,以及手动注册几个特殊的Bean
            * 解释下 BeanFactoryPostProcessor 和 BeanPostProcessor:
            *    1、两个接口的作用相同,都是Spring的Bean后置处理器接口,用于在Bean的初始化前后提供可扩展的空间
            *    2、不同点是:BeanFactoryPostProcessor是在实例化前被调用,而BeanPostProcessor是在实例化过程中使用
            */
			prepareBeanFactory(beanFactory);

			try {
                /**
                * postProcessBeanFactory()方法注释:
                *    在标准初始化之后修改内部Bean工厂,此时Bean都已经被加载,但还没有实例化。
                *    这步允许子类在某些ApplicationContext中注册特殊的BeanPostProcessors或者进行别的配置
                */
				postProcessBeanFactory(beanFactory);

                /**
                * 源码注释:调用在上下文中注册为bean的工厂处理器
                * 方法注释:
                *    实例化并调用所有已注册的 BeanFactoryPostProcessor bean
                *    如果给定顺序,则使用显式顺序注册。
                *    注意:必须在单例实例化之前调用。
                * 源码细节:
                *	 对BeanFactory进行遍历,进行addBeanPostProcessor以及setTempClassLoader
                */
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
                /**
                * 源码注释:注册拦截bean创建的bean处理器。
                * 方法注释:实例化并注册所有 BeanPostProcessor bean,且必须在应用程序 bean 的任何实例化之前调用。
                * 注意:到这里,Bean还是没有实例化
                */
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
                /**
                * 源码注释:初始化此上下文的消息源
                * MessageSource解读:主要用于解析消息,并支持消息的参数化和国际化,这里就不做深入了解了
                */
				initMessageSource();

                /**
                * 源码注释:为上下文初始化事件广播器(这里不展开看了)
                */
				initApplicationEventMulticaster();

                /**
                * 源码注释:在特定的上下文子类中初始化其他特殊bean。
                * 方法源码:
                *    从方法源码中可以看出这是一个空实现,有点钩子方法的意思(有大佬直接解读为钩子方法,这里没理解)
                * 设计模式中模板方法模式:
                *    包括模板方法和基本方法(抽象方法、具体方法、钩子方法)
                *    其中,钩子方法就是对于抽象方法或者接口中定义的一个方法,如果需要被调用,才设置为abstract,
                *    如果不需要,则空实现,这样继承之后就不需要再实现不需要的方法了
                */
				onRefresh();

                /**
                * 源码注释:检查侦听器bean并注册它们。(监听器不是重点)
                * 方法注释:添加实现 ApplicationListener 作为侦听器的 bean。不影响其他能被添加,但不能作为bean的监听器。
                */
				registerListeners();

                /**
                * 源码注释:实例化所有剩余的(非lazy-init)单例。
                * 重点:本方法完成此上下文的bean工厂的初始化,初始化所有剩余的非lazy-init的Singleton beans
                * BeanDefinition有一项配置就是void setLazyInit(boolean lazyInit);
                */
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:广播事件,ApplicationContext初始化完成
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// 销毁操作:销毁已经初始化的Singleton Beans,避免有些bean会一直占用资源
				destroyBeans();

				cancelRefresh(ex);

				throw ex;
			}

			finally {
				resetCommonCaches();
			}
		}
	}

三、第二层解读——refresh

接下来再对refresh()的各个方法进行解读

3.1 第一步:创建Bean容器前的准备工作

准备工作通过prepareRefresh()方法,源码如下:

	protected void prepareRefresh() {
		// 记录启动时间
		this.startupDate = System.currentTimeMillis();
        // 配置active和closed属性
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		initPropertySources();

		// 对xml配置文件进行校验
		getEnvironment().validateRequiredProperties();

        // 早期应用事件监听器,这个老版本的Spring是没有的
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// 早期应用事件收集器
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

3.2 第二步:创建Bean容器,加载并注册Bean

注意:这部分是在初始化Bean之前,进行BeanFactory的初始化以及加载和注册Bean。

首先是obtainFreshBeanFactory()方法

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 创建新的或重置已有的BeanFactory,加载和注册Bean
		refreshBeanFactory();
        // 将全新的BeanFactory返回
		return getBeanFactory();
	}

该方法最主要的步骤就是通过refreshBeanFactory()方法来创建新的或重置已有的BeanFactory,加载和注册Bean。该方法的源码:

	protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

在AbstractApplicationContext中将其定义为一个抽象方法,让子类进行实现。继续找寻,从其子类AbstractRefreshableApplicationContext中找到该方法的一个实现,源码如下:

	// 源码注释:
    // 此实现执行此上下文的底层bean工厂的实际刷新,关闭以前的bean工厂(如果有)并为上下文生命周期的下一阶段初始化一个新的bean工厂。
    @Override
	protected final void refreshBeanFactory() throws BeansException {
        /**
        * 如果ApplicationContext已经加载过BeanFactory了,则销毁所有Bean,且关闭BeanFactory
        * 解读:实际代码应用中,可以定义多个BeanFactory,但是这个判断条件只是判断当前的ApplicationContext是否有Bean工厂创建
        */
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
			DefaultListableBeanFactory beanFactory = createBeanFactory();
            // BeanFactory序列化
			beanFactory.setSerializationId(getId());
            /** 
            * 设置属性:是否允许Bean覆盖,是否允许循环引用
            * 针对BeanDefinition的覆盖问题:就是在配置文件中定义Bean时使用了相同的id或name
            *    默认情况下,在同一配置文件中重复会报错,如果不是同一配置文件会发生覆盖
            * 循环引用问题:默认是支持超过两个的bean之间循环引用
            */
			customizeBeanFactory(beanFactory);
            // 加载Bean到BeanFactory中
            // 在AbstractXmlApplicationContext中有该函数的众多实现,很复杂
			loadBeanDefinitions(beanFactory);
			synchronized (this.beanFactoryMonitor) {
				this.beanFactory = beanFactory;
			}
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

此处有一个细节点:为什么ApplicationContext实例化的是DefaultListableBeanFactory而不是其他的子类?

从本文最开始的BeanFactory继承图中可以看出DefaultListableBeanFactory对绝大部分子接口都有直接或间接地继承,处于最底端的它涵盖了大部分BeanFactory子接口的特有属性。

refreshBeanFactory()在关闭所有BeanFactory之后,就要对其进行重新创建和开启。其中涉及到两步关键操作:

customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);

首先是customizeBeanFactory(beanFactory),就是用于设置是否允许Bean覆盖和是否允许循环引用,源码如下:

	// 该部分的代码很简单,只要配置中设定了该属性,if判断不为null,就会来设置Bean覆盖和循环引用
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

当然,在默认情况下,对于循环依赖而言,可以进行超过两个Bean之间的循环引用。Spring允许循环依赖的情况是不允许开发者在A类的构造方法中依赖B类,然后在B类的构造方法中再依赖A类的情况出现。

接下来就是关键的加载Bean的步骤——loadBeanDefinitions()。该方法将根据配置,加载Bean,将其放入BeanFactory中。

	protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
			throws BeansException, IOException;

对该抽象方法找寻其主要实现,源码如下:

public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
    //...
    
    // 通过XmlBeanDefinitionReader加载bean定义
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// ①要为给定的BeanFactory创建一个新的XmlBeanDefinitionReader
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// ②使用此上下文的资源加载环境配置bean定义读取器。
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// ③允许子类提供读取器的自定义初始化,然后继续实际加载bean定义
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}
    
    // 使用①创建的XmlBeanDefinitionReader加载bean。
    // 注意:bean工厂的生命周期由refreshBeanFactory方法处理;因此这个方法只应该加载和注册bean定义。
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}
    
    // 初始化用于加载此上下文的 bean 定义的 bean 定义阅读器,当然主要还是用于子类复写
    protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
		reader.setValidating(this.validating);
	}
    
    //...
}

在loadBeanDefinitions()方法中,使用for循环不断遍历所有的resource,一个个进行配置文件读取。读取一个配置文件后,因为存在<context />、<aop />等多种标签,Spring会将所有标签绘制成DOM树,然后从树的根节点开始向下解析。读取过程从 AbstractXmlApplicationContext ——> XmlBeanDefinitionReader ——> DefaultBeanDefinitionDocumentReader。然后是解析过程,首先是<beans />标签的解析:

	// 在给定的根<beans/>元素中注册每个 bean 定义。
    protected void doRegisterBeanDefinitions(Element root) {
        // 这里,定义parent是因为<beans />内部也是可以再定义<beans />的,需要进行递归解析
		BeanDefinitionParserDelegate parent = this.delegate;
		this.delegate = createDelegate(getReaderContext(), root, parent);

		if (this.delegate.isDefaultNamespace(root)) {
            // 对profile属性的读取
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}

		preProcessXml(root);
		parseBeanDefinitions(root, this.delegate);
		postProcessXml(root);

		this.delegate = parent;
	}

    // 解析文档中根级别的元素:“import”、“alias”、“bean”
	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);
		}
	}

在bean标签的解析过程中,完成profile的读取后,又进入parseBeanDefinitions(root, this.delegate),进行解析文件中“import”、“alias”、“bean”等标签的解析。该方法内有两个分支,一个是parseDefaultElement(ele, delegate),一个是delegate.parseCustomElement(ele)。首先是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);
		}
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			doRegisterBeanDefinitions(ele);
		}
	}

从源码中可以看出,该方法主要针对import、alias、bean、beans标签进行解析。

3.2.1 bean属性注入

在这里,每个标签就不单独看了,拿出重点的bean标签作为范例,首先来看下用于解析bean标签的入口方法processBeanDefinition:

	// 处理给定的 bean 元素,解析 bean 定义并将其注册到注册表
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
		// ele中存储着标签节点信息,将其中各种信息提取出来,然后放入BeanDefinitionHolder中
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
            // 解析自定义属性
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
				// 进行bean注册
				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));
		}
	}

processBeanDefinition方法的第一步就是bean的属性解析及转换过程。

	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
		return parseBeanDefinitionElement(ele, null);
	}

	public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
		// 解析出两个最重要的属性:id和name
        String id = ele.getAttribute(ID_ATTRIBUTE);
		String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);

		List<String> aliases = new ArrayList<>();
        // 将name按照逗号、分号、空格进行切分,存储在字符串数组——别名列表中
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		String beanName = id;
        // 规则:如果id为空,则将aliases别名列表中第一个元素作为唯一标识
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isTraceEnabled()) {
				logger.trace("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
			checkNameUniqueness(beanName, aliases, ele);
		}

        // 创建beanDefinition,并将bean的属性放入其中
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
            // id和name都没有的话,执行if语句中的逻辑
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						beanName = this.readerContext.generateBeanName(beanDefinition);
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isTraceEnabled()) {
						logger.trace("Neither XML 'id' nor 'name' specified - " +
								"using generated bean name [" + beanName + "]");
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
			String[] aliasesArray = StringUtils.toStringArray(aliases);
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}

parseBeanDefinitionElement方法最重要的两个方面:一是设定了有关如何选择唯一标识的很多规则细节,另一方面就是将bean的属性放入BeanDefinition中。

	// 解析 bean 定义本身,而不考虑名称或别名。如果在解析 bean 定义期间出现问题,则可能返回null
    public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {

		this.parseState.push(new BeanEntry(beanName));

		String className = null;
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
		String parent = null;
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
            // 创建BeanDefinition,并设置类信息
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);

            // 将Bean的属性进行解析和放入BeanDefinition中
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            // 开始解析子元素,包括:meta、lookup-method、replaced-method、constructor-arg、property、qualifier
			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;
	}

以上过程完成后,bean的属性就已经放入BeanDefinition中。接下来就是bean的注册过程了。

   // 向给定的 bean 工厂注册给定的 bean 定义
   public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		// 使用主名称,开始bean注册过程
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

		// 如果有别名,还要根据别名再将bean注册一遍.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

    // 首要过程就是根据主名称来进行bean注册
	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);
			}
		}

        // bean名称记录,就是用于bean重名情况来进行bean覆盖操作所用
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		// 出现重名bean
        if (existingDefinition != null) {
            // bean覆盖没有开启的话,就会报错
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
            // 用框架定义的bean覆盖用户自定义的bean
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
            // 用新的bean覆盖旧的bean
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
            // 同等的新bean覆盖旧的bean
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
        // 没有出现重名bean
		else {
            // 判断是否有bean已经开始了初始化过程
			if (hasBeanCreationStarted()) {
				// 不能再修改启动时间集合元素(用于稳定迭代)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
                // 使用ArrayList,按照bean配置的顺序保存每一个注册的bean的名字
				this.beanDefinitionNames.add(beanName);
                // 手动注册SingletonBean
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
            // 重置bean定义缓存
			resetBeanDefinition(beanName);
		}
	}

到这一步位置,就已经完成了bean的解析,并将bean配置转化为一个个BeanDefinition,并且完成了注册。

3.3 第三步:准备Bean容器

在完成bean的解析和初始化过后,就要执行prepareBeanFactory(beanFactory)方法来准备bean工厂

    // 配置bean工厂的标准上下文特征,例如上下文的 ClassLoader 和后处理器。
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 设置类加载器等
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 使用上下文回调配置bean工厂
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// 以下依赖在自动装配时会忽略,Spring会通过其他方式来处理这些依赖
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 注册早期的事件监听器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 特殊bean处理
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 如果没有配置,则手动注册默认的environment、systemProperties和systemEnvironment
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

Bean容器准备好后,就是针对BeanFactoryPostProcessor、BeanPostProcessor等等的一系列注册以及实例化的操作。到目前为止,BeanFactory可以说已经创建完成了,并且所有实现了BeanFactoryPostProcessor和BeanPostProcessor接口的Bean也都完成了初始化。剩下没有初始化的就是Singleton Beans。

3.4 第四步:初始化所有Singleton Beans

最后的重点,就是finishBeanFactoryInitialization(beanFactory)来实例化所有剩余的没有设置懒加载的Singleton Beans。

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		/**
        * 转换服务:
        *    使用ConversionService进行转换。其主要的使用场景是可以将前端传过来的参数转化为后端参数。
        *    当后端Controller方法需要的是enum、Date等非基础类型,可以使用ConversionService进行转换
        * 对ConversionService的初始化包装在beanFactory.getBean()方法中
        */
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// 如果没有bean后置处理器,则注册一个默认的解析器
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 初始化LoadTimeWeaverAware类型的beans——该部分主要是AspectJ相关内容
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// 停止使用临时ClassLoader进行类型匹配
		beanFactory.setTempClassLoader(null);

		// 允许缓存所有bean定义元数据,而不需要进一步更改,这是初始化前最后的准备
		beanFactory.freezeConfiguration();

		// 开始初始化
		beanFactory.preInstantiateSingletons();
	}

3.4.1 bean的初始化过程

执行beanFactory.preInstantiateSingletons()开始初始化。实际的初始化是直接使用getBean()方法,而preInstantiateSingletons的其他操作主要就是针对配置了parent的父bean以及实现了SmartInitializingSingleton接口的bean进行的操作再区分。

	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 初始化所有非懒加载的Singleton beans
		for (String beanName : beanNames) {
            // 合并parent指定的父bean的配置
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 排除abstract=true、非懒加载的Singleton bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 处理FactoryBean
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
                // 普通Bean,直接调用getBean()方法初始化
				else {
					getBean(beanName);
				}
			}
		}
        
		// 回调实现了SmartInitializingSingleton接口的bean
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

这里说一下FactoryBean。其适用于一个Bean的实例创建很复杂的场景。单独实现一个类来实现FactoryBean<?>接口,在这个类中对实例创建进行封装。实际注解使用过程中,@Bean注解将其看做简单的Bean即可,这样隐藏了代码细节,不需要做过多的考虑,实际效果一样的。

接下来就是bean的实例化:

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

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

        // 拿到beanName
		final String beanName = transformedBeanName(name);
		Object bean;

		// 主动检查单例缓存中是否有手动注册的单例,即检查是否已经创建过了
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
            // 如果是普通bean,返回sharedInstance;如果是FactoryBean,返回创建的实例对象
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// 循环引用问题出现:如果已经创建过了beanName,抛异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 检查BeanDefinition是否存在于此容器中
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 如果不存在,就从父容器中检查
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
                    // 返回父容器的查询结果
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
                // args=null代表这是一个查询请求,不需要创建bean
				else if (args != null) {
					// 委托给父对象,返回父容器的查询结果
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// 无参数->委托给标准getBean方法
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
                // 如果typeCheckOnly为false,则将当前的beanName放入alreadyCreated集合中
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// 先初始化所有depends-on中定义依赖的所有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);
						try {
                            // 初始化被依赖项
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// 针对scope=singleton
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
                // 针对scope=prototype
				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 name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new 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实例的类型匹配
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

上述代码中,实际创建bean的就是createBean(beanName, mbd, args)方法。而createBean()方法在AbstractBeanFactory接口中,实现该接口的就是AbstractAutowireCapableBeanFactory类。这就是@Autowire注解。

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

		if (logger.isTraceEnabled()) {
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// 确保bean已经被解析
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 准备方法复写——涉及到bean标签的lookup-method属性和replaced-method属性
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
            // 创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}
createBean()通过调用doCreateBean()来执行创建操作。

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

		// 第一步:实例化bean——此时还未填充属性
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 解决循环依赖问题
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		Object exposedObject = bean;
		try {
            // 第二步:依赖注入——初始化bean实例,在这一步完成属性装配,来对实例化的bean进行赋值
			populateBean(beanName, mbd, instanceWrapper);
            // 第三步:执行bean的初始化方法
			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<>(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;
	}

3.4.2 属性注入

这里又涉及到多个过程,本次主要针对属性注入来说说。该部分最主要的过程是populateBean(beanName, mbd, instanceWrapper)方法。

	// 传入的mbd中存储了bean实例的所有属性
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// 在设置属性之前,给任何InstantiationAwareBeanPostProcessors机会修改bean的状态
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

		int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        // 处理自动装配类型——通过名字或者装配类型来找到所有属性值
        // 注意:这里还会考虑实际的依赖关系
		if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
			// Add property values based on autowire by name if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
				autowireByName(beanName, mbd, bw, newPvs);
			}
			// Add property values based on autowire by type if applicable.
			if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
				autowireByType(beanName, mbd, bw, newPvs);
			}
			pvs = newPvs;
		}

        // 后置处理器,以@Autowired注解的形式来将属性注入bean
		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        // 是否需要依赖检查
		boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

		PropertyDescriptor[] filteredPds = null;
        // 如果@Autowired注解有属性值的配置,则进行处理
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 这里会处理对注解形式的注入
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		if (needsDepCheck) {
			if (filteredPds == null) {
				filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
			}
			checkDependencies(beanName, mbd, filteredPds, pvs);
		}
        // 最后将所有得到的属性值设置给bean实例(注解的bean依赖注入除外,即主要是xml配置形式注入的属性)
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

现在使用较多的就是注解形式,对注解形式的属性注入,通过ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName)。该方法的主要实现为AutowiredAnnotationBeanPostProcessor类。其中涉及到InjuctionMetadata类,其封装了依赖的bean与被依赖bean的信息。

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
        // 定义了注入位置
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
		try {
            // 开始注入操作
			metadata.inject(bean, beanName, pvs);
		}
		catch (BeanCreationException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
		}
		return pvs;
	}

还有第二种就是通过xml配置形式注入的属性,通过applyPropertyValues(beanName, mbd, bw, pvs)方法注入。对xml配置形式来说,进行属性注入需要两步操作:一是需要进行转换,生成最终需要注入的类型的对象;剩下的就是进行注入操作。

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {
			return;
		}

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

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		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;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
                // 属性名
				String propertyName = pv.getName();
                // 未转换前的值
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
                // 转换后的值
				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();
		}

		// 属性注入,和之前的inject()方法类似
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

对转换操作来说,会根据参数类型:bean、Array、List、Set、Map、String等等不同类型进行具体的转换操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值