【Spring源码分析 1】使用Maven配置Spring步骤,Spring的Bean创建以及属性注入的源码分析

目录

1. Maven项目配置Spring

1.1 pom.xml中导入spring、日志和测试的依赖包

1.2 定义实体类

1.3 定义spring的配置文件applicationContext.xml(bean标签属性和子标签解释)

2. 测试代码 

3. 源码解析

3.1 解析bean,生成beanDefinition,注册到beanFactory

3.1.1 解析bean工作的关键实现

3.1.2 注册beanDefinition工作的关键实现

3.2 读取beanFactory中的beanDefinition,根据beanDefinition中bean的id、scope、class、init-method、property等信息创建bean实例、注入属性值并初始化

3.2.1 构造bean

3.2.2 属性赋值


1. Maven项目配置Spring

1.1 pom.xml中导入spring、日志和测试的依赖包

<!--        spring相关jar包,spring四个核心jar包:context、core、beans、expression,其中context依赖其他三个jar包+aop包,所以添加依赖时可以只添加context-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
<!--        日志jar包-->
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
<!--        日志的具体实现类-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
<!--        测试jar包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

1.2 定义实体类

在com.eleven.entity包下定义需要被spring管理的类,这里定义一个Account类,包含id, name和money三个属性。

package com.eleven.entity;


public class Account {

    private Integer id;
    private String name;
    private Double money;
    
    //省略 getter, setter, toString等方法
}

1.3 定义spring的配置文件applicationContext.xml(bean标签属性和子标签解释)

<bean>标签的属性

id: bean在IOC容器的map中的key,要求bean的id唯一,命名必须以字母开头,可以使用字母、数字、连字符、下划线、句号、冒号,不能出现其他特殊符号

class: bean对象的类名(全限定名)

parent:用来指定父Bean,这里应当写入父Bean的名称,可以为抽象Bean

scope:Bean的作用域,Spring内置的有singleton(单例,默认)、prototype(多例)、request(请求范围)、session(会话)、global-session(全局)

abstract:是否为抽象Bean,抽象Bean一般是提供一个Bean的模板,不包含class信息。其值只可为true或者false。

lazy-init:是否采用延迟初始化策略,对于非ApplicationContext的BeanFactory实现类来说,是默认开启延迟初始化策略的,只有在需要获取Bean的实例时候才会加载这个类,而ApplicationContext是默认关闭延迟初始化的,即在容器加载过程中完成类的加载操作,后续仅需要进行实例化即可。其值只可为true、false或者default。

autowire:即自动装配机制,当别的Bean需要依赖这个Bean的时候,是通过什么样的策略来识别这个Bean并注入到别的Bean。其值只可为byName、byType、constructor、default和no。具体可参照这篇博客:https://www.cnblogs.com/ViviChan/p/4981539.html

depends-on:表示依赖于指定的Bean,在当前Bean初始化的时候,会优先初始化depends-on中指定的Bean

autowire-candidate:Bean的候选属性,同样可以参照上面的博客。其值只可为true、false或者default。

primary:表示是否是优先的Bean,如果容器中有多个同一类型的Bean,如果不指定一个primary为true的Bean,那么在注入时就会因为存在多个类型匹配的Bean而抛出异常。当指定了一个primary为true的Bean后,就不会因此而抛出异常。其值只可为true、false

init-method:Bean的默认初始化方法,在bean实例构造后立即执行

destory-method:Bean的默认销毁方法

factory-bean:指向实例工厂方法的bean

factory-method:实例工厂方法

子标签

<property>:通过成员变量注入

<constructor-arg>:通过构造方法注入

<description>:Bean的描述信息

<meta>:用来存储一些键值型的参数,通过调用BeanDefinition的getAttribute方法获得

<lookup-method>:用来通过方法来实现依赖注入,可以参考博客:https://www.cnblogs.com/ViviChan/p/4981619.html

<replaced-method>:用来替换该Bean存在的方法,其属性有name和replacer。可以参考这篇博客

<qualifier>:指定Bean的一个特殊名称,防止在注入时其它Bean时因为有多个匹配的Bean而发生异常。

Spring配置文件详解https://baijiahao.baidu.com/s?id=1627706479612877818&wfr=spider&for=pc

样例中添加bean节点,用于创建一个Account实例

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--bean-->
    <bean id="account1" class="com.eleven.entity.Account">
        <property name="id" value="10"/>
        <property name="name" value="my"/>
        <property name="money" value="100"/>
    </bean>

</beans>

2. 测试代码 

加载xml配置文件,创建IOC容器;

import com.eleven.entity.Account;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main1 {

    @Test
    public void test1(){
        // 加载classpath下的xml配置文件是,创建spring容器(我们源码解析这一步)
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

        // 从spring容器中获取bean
        Account account1 = (Account) ac.getBean("account1");
        System.out.println(account1);

    }

}

3. 源码解析

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");  //加载xml配置文件,创建IOC容器

ApplicationContext的抽象实现类AbstractApplicationContext , 实现应用上下文的一些具体操作

AbstractApplicationContext的具体实现类ClassPathXmlApplicationContext,用于加载xml配置文件

加载xml配置文件并解析创建bean的入口方法就是AbstractApplicationContext::refresh()

    // configLocations就是classpath资源文件夹下xml配置文件的文件名;
    // refresh 判断是否重新解析xml配置文件,默认为true;
    // parent 父容器, 创建的IOC容器可以访问parent容器的资源
    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        // 将配置文件路径赋给IOC容器的configLocations属性
        this.setConfigLocations(configLocations);  
        if (refresh) {
            // 继承AbstractApplicationContext的refresh(),是解析配置文件的入口
            // 重要任务: 解析xml配置文件中的bean节点,为其生成beanDefinition, 并注册到beanFactory
            this.refresh();
        }

    }

3.1 解析bean,生成beanDefinition,注册到beanFactory

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

BeanFactory的具体实现类DefaultListableBeanFactory,其中两个重要属性:

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

private volatile List<String> beanDefinitionNames = new ArrayList(256);

beanDefinitionMap 记录了beanName的beanDefinition,所以要求保证beanName唯一,也就是说xml中bean节点的id唯一;

beanDefinitionNames 记录了所有beanName, 用于断言检查beanName所对应的beanDefinition是否已经被创建,不重复创建。

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {

            // 1. 创建beanFactory, 得到beanDefinition
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

            // 2. 根据beanDefinition中保存的bean的定义信息,创建bean
            // 省略代码

        }
    }

    // 1. 创建beanFactory, 得到beanDefinition
    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 调用AbstractRefreshableApplicationContext::refreshBeanFactory方法创建beanFactory并返回
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }

调用AbstractRefreshableApplicationContext::refreshBeanFactory()方法,主要做两件事:

  • 检查spring容器(也就是ApplicationContext实例)是否已经存在beanFactory, 如果存在,将销毁所有bean并关闭该beanFactory, 以保证在refresh之后使用的是新创建的beanFactory
  • 创建beanFactory,调用AbstractXmlApplicationContext::loadBeanDefinition() 解析bean生成beanDefinition
    protected final void refreshBeanFactory() throws BeansException {
        // 如何beanFactory已经存在,则销毁所有bean并关闭该beanFactory
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            // 创建beanFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);
            // 加载bean节点,给它生成BeanDefinition, 并注册到beanFactory中, 这些动作交给AbstractXmlApplicationContext的loadBeanDefinitions执行
            this.loadBeanDefinitions(beanFactory);
            // 省略代码

        } catch (IOException var5) {
            // 省略代码
        }
    }

AbstractXmlApplicationContext::loadBeanDefinitions()又干了些什么呢,

主要是为beanFactory生成一个XmlBeanDefinitionReader对象,可以认为是bean的加载器,用它来读取xml中的bean:

this.loadBeanDefinitions(beanDefinitionReader); -> reader.loadBeanDefinitions(configLocations);

    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {

        //创建XmlBeanDefinitionReader,即创建Bean加载器,读取Bean的信息
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        // 省略代码

        // 读取bean
        this.loadBeanDefinitions(beanDefinitionReader);
    }


    // 读取bean
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {

        // 先解析Resource资源
        Resource[] configResources = this.getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }

        // 再解析xml
        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
            // Bean加载器读取xml配置文件中的bean定义信息
            reader.loadBeanDefinitions(configLocations);
        }

    }

AbstractXmlApplicationContext使用XmlBeanDefinitionReader::loadBeanDefinitions()来读取xml配置文件中的bean节点定义信息,加载xml配置文件创建Resource资源对象,然后又转换为InputSource,调用XmlBeanDefinitionReader::doLoadBeanDefinitions()加载xml配置文件,生成document对象

    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
            // 解析xml文件
            Document doc = this.doLoadDocument(inputSource, resource);
            // 为bean生成beanDefinition,注册到beanFactory, 并返回bean的个数
            int count = this.registerBeanDefinitions(doc, resource);
            // 省略代码

            return count;
        } catch (Throwable e) {
            // 各种异常捕获
        }
    }

    // 为bean生成beanDefinition,注册到beanFactory, 并返回bean的个数
    public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        // 创建document对象的bean加载器
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        // 获取已经生成的beanDefinition个数
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        // 解析当前配置文件的document对象的bean,生成beanDefinition并注册到beanFactory
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        // 返回当前配置文件设置的bean个数
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

DefaultBeanDefinitionDocumentReader::registerBeanDefinitions()获取<beans>根节点->

this.parseBeanDefinitions(root, this.delegate);  // 调用doRegisterBeanDefinitions解析根节点的profile信息,然后调用parseBeanDefinitions解析所有的子节点, 遍历所有的子节点,当遇到默认标签的节点->

this.parseDefaultElement(ele, delegate); // 判断标签类型,如果是<bean>类型->

this.processBeanDefinition(ele, delegate); // 当碰到<bean>节点,processBeanDefinition来正式执行解析bean,生成beanDefinition和注册的工作

    public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        // doc.getDocumentElement()获取<beans>根节点
        this.doRegisterBeanDefinitions(doc.getDocumentElement());
    }

    // 省略函数代码

    // 正式开始解析bean和生成beandefinition
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // BeanDefinitionHolder存储该bean生成的beanDefinition,beanName和aliases,也就是BeanDefinition及其名称和别名
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            // 装饰beanDefinition,二次解析,作用是解析默认标签中的自定义标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
                //this.getReaderContext().getRegistry()获取BeanDefinitionRegistry注册器,作用是将beanname:beanDefinition注册到beanFactory中
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
            } // 省略异常捕获处理

            this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }

    }

3.1.1 解析bean工作的关键实现

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);

BeanDefinitionParserDelegate的实例delegate调用parseBeanDefinitionElement()方法解析bean,生成beanDefinition,beanName和aliases,封装成一个BeanDefinitionHolder对象,相当于BeanDefinition的持有者

    @Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
    //获取bean的id
	String id = ele.getAttribute(ID_ATTRIBUTE);	
    //获取bean的name	
	String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);	
	//List集合保存bean的名称
	List<String> aliases = new ArrayList<>();
	if (StringUtils.hasLength(nameAttr)) { //
		//对bean的name分割,并将所有结果存入aliases
		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); //将aliases中第一个name作为beanName
		if (logger.isTraceEnabled()) {
			logger.trace("No XML 'id' specified - using '" + beanName +
					"' as bean name and " + aliases + " as aliases");
		}
	}

	if (containingBean == null) { 
		//检查beanName是否唯一(BeanDefinitionParserDelegate维护一个set集合usedNames,记录已使用的beanName和aliases),如果beanName重复定义,则抛出异常
		checkNameUniqueness(beanName, aliases, ele);
	}

	//解析bean节点的属性和子标签, 封装生成beanDefinition()
	AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);

	if (beanDefinition != null) {

		// 省略代码,如果beanName为空,生成一个可用的beanName(默认首字母小写的类名)

		//将解析后的信息封装到BeanDefinitionHolder(可以认为是beanDefinition的载体)
		String[] aliasesArray = StringUtils.toStringArray(aliases);
		return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
	}
	return null;
}

   

parseBeanDefinitionElement()    //正式解析bean的方法,获取bean节点的属性和子标签, 封装生成beanDefinition

    @Nullable
    public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {

        this.parseState.push(new BeanEntry(beanName));
        // 解析bean的class属性,获取类名
        String className = null;
        if (ele.hasAttribute("class")) {
            className = ele.getAttribute("class").trim();
        }

        // 解析父bean,该bean可以从parent bean中继承它的同名属性值
        String parent = null;
        if (ele.hasAttribute("parent")) {
            parent = ele.getAttribute("parent");
        }

        try {
            // 通过类名和父bean,创建BeanDefinition
            AbstractBeanDefinition bd = this.createBeanDefinition(className, parent);
            // 解析bean的属性:scope、abstract、lazy-init、autowire、init-method、destroy-method、factory-method、factory-bean
            this.parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, "description"));
            // 下列解析bean的子标签
            this.parseMetaElements(ele, bd);
            this.parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
            this.parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
            this.parseConstructorArgElements(ele, bd);
            this.parsePropertyElements(ele, bd);  //解析Property子标签,将name和value存在到propertyValues对象
            this.parseQualifierElements(ele, bd);
            bd.setResource(this.readerContext.getResource());
            bd.setSource(this.extractSource(ele));
            AbstractBeanDefinition var7 = bd;
            return var7;
        } catch (Throwable e) {
            // 省略各种异常捕获
        } finally {

            this.parseState.pop();
        }

        return null;
    }

3.1.2 注册beanDefinition工作的关键实现

调用工具类BeanDefinitionReaderUtils::registerBeanDefinition()方法,传入beanDefinition持有器和注册器,

通过注册器调用实现类DefaultListableBeanFactory实现的registerBeanDefinition()方法将beanName:beanDefinition添加到beanFactory的beanDefinitionMap中,并将beanName添加到beanDefinitionNames列表中

    public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        // 传入beanDefinition持有器,获取beanName
        String beanName = definitionHolder.getBeanName();
        // 通过注册器将beanDefinition注册到beanFactory
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                registry.registerAlias(beanName, alias);
            }
        }

    }
        public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        // 省略代码

        // 将beanName:deanDefinition 添加到beanFactory的beanDefinitionMap中,并将beanName添加到beanDefinitionNames列表中
        this.beanDefinitionMap.put(beanName, beanDefinition);
        this.beanDefinitionNames.add(beanName);
        this.removeManualSingletonName(beanName);
            
    }

3.2 读取beanFactory中的beanDefinition,根据beanDefinition中bean的id、scope、class、init-method、property等信息创建bean实例、注入属性值并初始化

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {

            // 1. 创建beanFactory, 得到beanDefinition
            // 省略代码

            // 2. 根据beanDefinition中保存的bean的定义信息,创建bean(所有非懒加载的单例类)
            this.finishBeanFactoryInitialization(beanFactory);

        }
    }


    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 省略代码

        // 关键代码:准备实例化单例bean
        beanFactory.preInstantiateSingletons();
    }

beanFactory调用preInstantiateSingletons()方法(上面我们已经知道beanFactory对象是实现类DefaultListableBeanFactory的实例,preInstantiateSingletons()被DefaultListableBeanFactory实现)

    public void preInstantiateSingletons() throws BeansException {
        // 省略代码

        // 获取所有的beanDefinition对应的beanName,并遍历
        List<String> beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            String beanName;
            Object bean;
            do {
                while(true) {
                    RootBeanDefinition bd;
                    do {
                        do {
                            do {
                                // 省略代码

                                // 根据beanName从IOC容器中取出BeanDefinition,如果BeanDefinition的父类不为空,则把父类的beanDefinition合并,得到RootBeanDefinition。也就是说getMergedLocalBeanDefinition的作用是将bean和可能存在的父bean融合,生成的这个RootBeanDefinition中保存了该bean的完整的定义
                                beanName = (String)var2.next();
                                bd = this.getMergedLocalBeanDefinition(beanName);

                            // 抽象类、多例、懒加载的bean在创建IOC容器时不实例化
                            } while(bd.isAbstract()); 
                        } while(!bd.isSingleton());
                    } while(bd.isLazyInit());

                    // 如果bean是工厂bean,在beanName前面加上"&"
                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }

                    // 实例化bean
                    this.getBean(beanName);
                }
            } while(!(bean instanceof FactoryBean));

            FactoryBean<?> factory = (FactoryBean)bean;
            boolean isEagerInit;
            if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                SmartFactoryBean var10000 = (SmartFactoryBean)factory;
                ((SmartFactoryBean)factory).getClass();
                isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
            } else {
                isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
            }

            if (isEagerInit) {
                this.getBean(beanName);
            }
        }
    }

AbstractBeanFactory::getBean()-> AbstractBeanFactory::doGetBean()

Object sharedInstance = this.getSingleton(beanName); 先从三级缓存中获取,如果不存在->

委托父beanFactory实例化该bean实例,如果父beanFactory不存在->

实现一个beanFactory接口函数来实例化该bean实例

    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
        // beanName别名转换
        String beanName = this.transformedBeanName(name);
        //从三级缓存中尝试获取该bean
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        if (sharedInstance != null && args == null) {
            // 省略代码

            // 如果该单例bean已经创建,将其取出赋值给bean,后续直接返回这个bean
            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {
            // 省略代码

            // 如果有父beanFactory, 委托给父beanFactory实例化bean, 并返回bean
            
            // 如果没有父beanFactory
            try 
                // 根据原始BeanDefinition以及可能存在的父BeanDefinition中的bean定义信息合并生成RootBeanDefinition
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                //省略代码

                // 如果bean定义为单例模式(bean节点中scope属性默认singleton单例模式)
                if (mbd.isSingleton()) {
                    // 调用DefaultSingletonBeanRegistry的getSingleton方法
                    // public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory)
                    // 这里用了一个BeanFactory得匿名内部类对象,实现BeanFactory接口中唯一一个getObject()方法,用于获取bean实例
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } 
                // 如果bean定义为多例或其他模式
                // 省略代码

            } catch (BeansException var26) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var26;
            }
        }

        // 省略代码
        return bean;
        
    }

DefaultSingletonBeanRegistry::getSingleton() 先从三级缓存中获取bean的过程

三级缓存机制

注:图片来自https://www.cnblogs.com/wyq178/p/11415877.html

    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        // 一级缓存:singletonObjects单例缓存
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            synchronized(this.singletonObjects) {
                // 如果一级缓存中没有,则到二级缓存earlySingletonObjects中找
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        // 如果二级缓存中没有,则到三级缓存singletonFactory中找,同时将该bean在一级缓存和二级缓存中的记录清除
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        // 返回缓存中的实例
        return singletonObject;
    }

如果缓存中没有该bean,并且没有父beanFactory来创建该bean, 则调用DefaultSingletonBeanRegistry的getSingleton方法来自己创建bean

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null) {
                //省略代码

                try {
                    // 使用singletonFactory获取该bean实例
                    singletonObject = singletonFactory.getObject();
                    // 如果程序流走到这里,说明该singletonObject之前没有被创建过,标识为新的单例
                    newSingleton = true;
                } catch (Throwable e) {
                    // 省略代码,各种异常处理
                }  finally {
                    // 省略代码
                }

                // 将新的单例添加到IOC容器
                if (newSingleton) {
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject;
        }
    }

singletonFactory的getObject()方法在匿名内部类中实现,调用AbstractAutowireCapableBeanFactory::createBean()方法

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        // 省略代码

        RootBeanDefinition mbdToUse = mbd;
        // 解析bean的class
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        //  省略代码

        try {
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var9) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
        }

        Object beanInstance;
        // 省略代码: 获取代理对象,如果存在,则返回代理对象

        try {
            // 创建bean实例
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            // 省略代码

            return beanInstance;
        } // 省略各种异常捕获处理
    }

AbstractAutowireCapableBeanFactory::doCreateBean()

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

        // 创建一个bean加工器
        BeanWrapper instanceWrapper = null;

        if (mbd.isSingleton()) {
            // 该bean是单例,并且程序流走到这,说明IOC容器的单例中没有该bean实例, 则继续尝试从缓存(factoryBeanInstanceCache,ConcurrentMap)中获取该单例,如果获取成功,将从缓存中删除该单例的键值对
            
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            // 1. 构造bean
            // 如果缓存中没有该bean, 则开始创建该bean,返回该bean实例的加工器
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        // 从bean加工器中获取bean实例
        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        //   
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {

                    // 正在被spring实例化的bean进行@Autowired和@Value扫描,扫描到类里面属性和方法上面如果有注解,就会把对应的方法或者属性封装起来,最终封装成InjectionMetadata对象
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }


        boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
            // 为避免后期循环依赖,可以在bean初始化完成前将创建实例的beanFactory注册到单例工厂singletonFactories中
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            // 2. 属性赋值
            // 依赖注入, 为bean的指定属性赋值
            this.populateBean(beanName, mbd, instanceWrapper);
            // 3. 初始化bean
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);

        } // 省略异常捕获处理代码
     

        //省略代码

        try {
            // 4. 根据scope注册bean
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

3.2.1 构造bean

instanceWrapper = this.createBeanInstance(beanName, mbd, args);

获取bean的class对象,根据参数解析构造方法或工厂方法

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 获取类class对象
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        // 省略代码

            // 获取创建bean实例的回调Supplier
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            // 省略代码,校验

                boolean resolved = false;
                boolean autowireNecessary = false;
                // 如果参数为空,解析无参构造函数
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        // 一个类可能有多个构造函数,每个构造函数都有不同的参数,所以调用前需要先根据参数确定构造函数或对应的工厂方法
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }

                if (resolved) {
                    // 判断是构造函数自动注入还是默认构造函数构造
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    // 如果上面确定构造函数或工厂方法失败,resolved为false,则继续根据参数解析构造函数
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        ctors = mbd.getPreferredConstructors();
                        // 判断是构造函数自动注入还是默认构造函数构造
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            
    }

我的例子中定义的bean对应的类只有一个默认无参构造函数,所以最终会运行this.instantiateBean(beanName, mbd);来创建bean实例

    protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            // 省略代码

                // 拿到bean实例
                beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);

            // 生成该bean的加工器,同时会把bean实例赋给加工器的wrapperObject和rootObject属性
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            this.initBeanWrapper(bw);
            return bw;
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
        }
    }

最终是通过BeanUtils工具类来创建该bean实例

    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // 省略代码,如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代码,因为可以在创建代理的同时将动态方法织入类中,如果没有需要动态改变的方法,直接反射创建实例

                    // 获取类class对象
                    Class<?> clazz = bd.getBeanClass();
                    // 省略代码:检查如果该class对应的是接口,则抛出异常(不允许实例化接口)

                    try {
                        // 省略代码

                            // 获取无参构造器(private权限的也能获取)
                            constructorToUse = clazz.getDeclaredConstructor();

                        //声明beanDefinition解析得到的创建bean的构造函数或工厂方法
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    } // 省略异常捕获处理
                }
            }

            // 最终调用BeanUtils工具类来使用该类的构造器初始化一个实例
            return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
        } else {
            return this.instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

BeanUtils::instantiateClass中主要是解析构造参数,最后通过构造器.newInstance(参数列表)来得到一个实例对象

    public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {

        try {
            // 省略代码

                // 获取构造器参数类型
                Class<?>[] parameterTypes = ctor.getParameterTypes();

                // 解析构造参数                
                Object[] argsWithDefaultValues = new Object[args.length];
                for(int i = 0; i < args.length; ++i) {
                    if (args[i] == null) {
                        Class<?> parameterType = parameterTypes[i];
                        argsWithDefaultValues[i] = parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null;
                    } else {
                        argsWithDefaultValues[i] = args[i];
                    }
                }

                // 反射:通过构造函数和参数初始化实例bean
                return ctor.newInstance(argsWithDefaultValues);
            
        } // 省略异常捕获处理
    }

3.2.2 属性赋值

this.populateBean(beanName, mbd, instanceWrapper);

属性值在解析bean的时候保存在beanDefinition的propertyValues属性中,有几个<property>子标签,propertyValues中就会记录多少个propertyValue对象,propertyValue包含name属性和value属性,对应<property>的name和value属性

在注入属性之前,AbstractAutowireCapableBeanFactory::applyPropertyValues先对每个propertyValue解析value

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        // 省略代码

            // 获取bean的所有property子标签的name属性
            PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
            // 获取参数注入方式,主要有byName和byType两种方式,默认byName
            int resolvedAutowireMode = mbd.getResolvedAutowireMode();
            if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
                MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
                if (resolvedAutowireMode == 1) {
                    this.autowireByName(beanName, mbd, bw, newPvs);
                }

                if (resolvedAutowireMode == 2) {
                    this.autowireByType(beanName, mbd, bw, newPvs);
                }

                pvs = newPvs;
            }

            // 省略代码,

            if (pvs != null) {
                // 进行属性值依赖注入
                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }

        }
    }



    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        // 省略代码

                // 获取bean下所有子标签的name和value值(PropertyValue)
                original = mpvs.getPropertyValueList();
            
            // 类型自定义转换器,如果没有,则使用该bean的加工器
            TypeConverter converter = this.getCustomTypeConverter();
            if (converter == null) {
                converter = bw;
            }

            // 生成bean实例的属性值解析器
            BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
            List<PropertyValue> deepCopy = new ArrayList(original.size());
            boolean resolveNecessary = false;
            Iterator var11 = original.iterator();
            // 迭代property,解析value
            while(true) {
                while(var11.hasNext()) {
                    // PropertyValue包含两个重要属性:name记录bean实例属性名, value记录属性值
                    PropertyValue pv = (PropertyValue)var11.next();
                    
                    // 省略代码: 进行value的解析等工作

                    deepCopy.add(pv);
  
                }

                try {
                    // 将property定义的属性值注入给bean的属性
                    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
                    return;
                } // 省略异常捕获处理代码
            }
        }
    }

对propertyValue解析value之后,AbstractPropertyAccessor::setPropertyValues开始迭代每个propertyValue,调用AbstractNestablePropertyAccessor::setPropertyValue进行属性注入

    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {
        // 省略代码
        // 迭代注入属性
        List<PropertyValue> propertyValues = pvs instanceof MutablePropertyValues ? ((MutablePropertyValues)pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues());
        Iterator var6 = propertyValues.iterator();

        while(var6.hasNext()) {
            PropertyValue pv = (PropertyValue)var6.next();

            try {
                this.setPropertyValue(pv);

            } // 省略异常捕获处理代码
        }

        // 省略代码: 异常处理
    }

AbstractNestablePropertyAccessor::setPropertyValue先会对value进行预处理, 最终调用BeanWrapperImpl::setValue()方法正式执行反射赋值

    public void setPropertyValue(PropertyValue pv) throws BeansException {
        //对属性访问表达式的细化和归类,PropertyTokenHolder中有三个属性,其中actualName代表name,canonicalName代表整个表达式name[0],而key则代表0这个下标位置
        AbstractNestablePropertyAccessor.PropertyTokenHolder tokens = (AbstractNestablePropertyAccessor.PropertyTokenHolder)pv.resolvedTokens;
        if (tokens == null) {
            String propertyName = pv.getName();

            AbstractNestablePropertyAccessor nestedPa;
            try {
                nestedPa = this.getPropertyAccessorForPropertyPath(propertyName);

            } // 省略异常处理

            tokens = this.getPropertyNameTokens(this.getFinalPath(nestedPa, propertyName));
            if (nestedPa == this) {
                pv.getOriginalPropertyValue().resolvedTokens = tokens;
            }

            // tokens包装了属性值
            nestedPa.setPropertyValue(tokens, pv);
        } else {
            this.setPropertyValue(tokens, pv);
        }

    }

    protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        if (tokens.keys != null) {
            this.processKeyedProperty(tokens, pv);
        } else {
            // 因为我的<bean>的子标签<property>的value都设置的字面量,所以程序流会走到这里,执行processLocalProperty方法
            this.processLocalProperty(tokens, pv);
        }

    }


    private void processLocalProperty(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) {

        // 获取property处理器
        AbstractNestablePropertyAccessor.PropertyHandler ph = this.getLocalPropertyHandler(tokens.actualName);
        if (ph != null && ph.isWritable()) {
            Object oldValue = null;

            PropertyChangeEvent propertyChangeEvent;
            try {
                Object originalValue = pv.getValue();
                Object valueToApply = originalValue;
                // 省略代码

                // valueToApply中保存property的value值,property处理器进行正式注入属性值的工作
                ph.setValue(valueToApply);

            } // 省略异常捕获处理

        } 
        // 省略代码
    }

BeanWrapperImpl::setValue先获取属性的set方法,ReflectionUtils工具类makeAccessible方法对方法进行访问权限处理(使private等方法可通过反射访问),通过method.invoke(实例,参数),将参数传给该实例的set方法并执行,赋值给实例的属性。

public void setValue(@Nullable Object value) throws Exception {
            // 获取属性的set方法(这里默认类提供set+首字母大写属性名()方法,通过jdk动态代理执行该方法,传入参数,给属性赋值)
            Method writeMethod = this.pd instanceof GenericTypeAwarePropertyDescriptor ? ((GenericTypeAwarePropertyDescriptor)this.pd).getWriteMethodForActualAccess() : this.pd.getWriteMethod();
            // 省略代码

                // 处理方法的访问权限,是方法可通过反射访问
                ReflectionUtils.makeAccessible(writeMethod);
                // 动态代理执行set方法,传入实例和参数值
                writeMethod.invoke(BeanWrapperImpl.this.getWrappedInstance(), value);
           
        }
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值