Spring IOC容器原理详解

Spring

概述

关于Spring

Spring作为目前Java领域最热门的开发框架,是一个Java程序员最常用的框架,并且在面试中Spring也是面试官考核的重要部分。目前Spring家族已经发展的非常壮大,包括目前大火的微服务框架Spring Boot和Spring Cloud等,而这些框架都离不开Spring最早期的Spring Core,也就是Spring最核心的部分。Spring Core的核心就是IOC容器,此文着重介绍Spring IOC原理

前言

对本文的理解建立在你有Spring IOC的使用经验,如果你连玩意怎么用都还不知道,那可能理解本文相对困难


IOC原理

IOC(Inversion of Control)也就是控制反转,它本质上是一种思想,Spring IOC的设计正是利用了控制反转的思想实现,所以想要理解Spring IOC先要理解控制反转思想

1.DI依赖注入

DI(Dependency Injection)即依赖注入,想要理解IOC首选我们要理解什么是依赖注入。下面图解一下DI

未实现控制反转的依赖注入
下层控制上层

如上图但我们设计一个行李箱时有如下步骤:设计轮子﹣>设计好轮子后根据轮子设计底盘﹣>设计好底盘后根据底盘设计箱体﹣>设计好箱体后根据箱体设计行李箱,于是就存在图示的依赖关系。
假设此时产品经理告诉我们要把轮子的尺寸加大一码,那就意味着:重新设计轮子﹣>根据新轮子重新设计底盘﹣>根据新底盘重新设计箱体﹣>根据箱体重新设计行李箱。这对于程序员来说是一件非常头秃的事,要和产品经理干架了。
咋们根据代码来看一下,依据上面设计行李箱的流程有如下代码关系:


代码1

上层类的构造器中都new了下层类的实例,如果此时我们希望轮子Tire的size字段是可变的,那代码关系就转变成下面这样:


代码2

显然,因为修改Tire导致了整个上层的每个类都需要被修改,代码可维护性很差
实现控制反转后的依赖注入
上层控制下层

如上图但我们设计一个行李箱时有如下步骤:设计行李箱﹣>设计好行李箱后根据行李箱设计箱体﹣>设计好箱体后根据箱体设计底盘﹣>设计好底盘后根据底盘设计轮子,也就是下层类作为参数传入上层类,即控制反转实现上层控制下层。
结合实际代码看一下:


代码3

如果此时我们希望可以动态修改Tire的size只需要做如下的修改:


代码4

显然代码可维护性增强了,上层类不在需要依据底层类的变化做出修改,实现各个部分代码之间的解耦

2.IOC和DI、DL之间的关系

IOC和DI、DL之间的关系

实现IOC控制反转的方式有两种,一种是DL依赖查找,目前已经基本被抛弃,另一种就是DI依赖注入,是当今IOC的主流实现方式,Spring就是利用DI的方式来实现IOC控制反转。
Spring的依赖注入方式有四种:

  • Setter方式(Set注入)
  • Constructor(构造器注入)
  • Annotation(注解注入)
  • Interface(接口注入)

3.依赖倒置原则、IOC、DI、IOC容器之间的关系

依赖倒置原则、IOC、DI、IOC容器之间的关系

依赖倒置原则是一种高层模块不应该依赖于底层模块的思想,根据这种思想于是有了IOC控制反转的设计,而实现控制反转需要用到DI依赖注入的方法,Spring则依据IOC提出了容器的概念,也就是Spring IOC容器。 Spring的IOC容器管理bean的生命周期和控制bean之间的依赖注入,IOC容器有如下优点:

  • 避免在各处使用new来创建类,并且可以做到统一维护
  • 创建实例时不需要了解其中的细节(自动处理类之间的依赖关系,自动装配)

深入Spring IOC容器

1.Spring IOC容器工作机制

Spring IOC容器工作机制

Spring IOC容器工作机制分为如下步骤:

  1. 读取Bean配置信息,生成bean配置注册表,配置信息包括XML配置文件,@Configuration注解的配置类,@Autowired自动注入等
  2. 根据bean配置注册表实例化bean
  3. 建立好bean实例之间的依赖关系,并且把bean实例存放IOC容器的Bean缓存池中
  4. 应用程序使用bean实例

2.Spring IOC核心接口

  1. BeanDefinition:主要用来描述Bean的定义,包括类型、属性、是否单例、是否懒加载、相关依赖等,Spring IOC容器在启动时会将我们在XML配置中或者注解的Bean解析成BeanDefinition,Spring IOC容器通过BeanDefinition对Bean进行管理和依赖装配
  2. BeanFactory:此接口是Spring IOC最底层核心接口,Spring IOC容器实现的架构基础,主要提供以下功能:
  • 提供IOC配置机制
  • 包含Bean的各种定义,便于实例化Bean
  • 建立Bean之间依赖关系
  • Bean生命周期控制
  1. ApplicationContext:建立在BeanFactory的基础之上,如果说BeanFactory是一辆汽车,那ApplicationContext就是一辆更高级的汽车拥有更多功能,它不仅仅拥有BeanFactory的能力,通过继承ResourceLoader、ApplicationEventPublisher等接口使它拥有加载资源文件和监听等能力。可以说BeanFactory构建了Spring IOC的基础,ApplicationContext在基础之上更进一步,其主要面向使用Spring的开发者

3.深入Spring IOC源码

在大致了解了Spring IOC几个关键的接口以后,我们再深入到源码当中,深层次剖析。我们知道Spring IOC处理的最重要的两件事就是管理Bean的生命周期和处理Bean之间的依赖关系,下文我们也着重深入源码研究Spring IOC容器是怎样做到这两点的

新建项目

咋们新建一个Spring Boot项目进行研究(我使用的是Spring Boot
2.2.1.RELEASE,可能由于Spring版本不同,下文的部分代码会有一些不同,但是基本没什么差异)


项目目录结构

很简单,一个Spring Boot的启动类、一个实体类、一个配置类
实体类:

public class User {
    private String username;
    private String pwd;

    public String getUsername() {
        return username;
    }

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

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
}
  • 已Spring Boot启动
    配置类:
@Configuration
public class Config {
    @Bean
    public User user(){
        User user = new User();
        user.setUsername("ling");
        user.setPwd("123");
        return user;
    }
}

最后启动类:

@SpringBootApplication
public class IocDemoApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(IocDemoApplication.class, args);
        User user = (User) applicationContext.getBean("user");
        System.out.println(user.getUsername() + " " + user.getPwd());

//      ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("");
    }

}

这基本就是我们使用Spring IOC一个最基本简单的案例,在配置类中将User实体注册到容器中,在启动类里通过容器把User实例取出来。

BeanFactory初始化和注册Bean定义

咋们根据Spring Boot的启动代码来深入,先看看SpringApplication.run(IocDemoApplication.class, args)的run方法是怎样的

// SpringApplication.class
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        return run(new Class[]{primarySource}, args);
    }

里面调用run(new Class[]{primarySource}, args),继续进入方法

// SpringApplication.class
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
        return (new SpringApplication(primarySources)).run(args);
    }

再次调用了run(args),继续进入方法

// SpringApplication.class
public ConfigurableApplicationContext run(String... args) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ConfigurableApplicationContext context = null;
        Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
        this.configureHeadlessProperty();
        SpringApplicationRunListeners listeners = this.getRunListeners(args);
        listeners.starting();

        Collection exceptionReporters;
        try {
            ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
            ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
            this.configureIgnoreBeanInfo(environment);
            Banner printedBanner = this.printBanner(environment);
            context = this.createApplicationContext();
            exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
            this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
            this.refreshContext(context);
            this.afterRefresh(context, applicationArguments);
            stopWatch.stop();
            if (this.logStartupInfo) {
                (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
            }

            listeners.started(context);
            this.callRunners(context, applicationArguments);
        } catch (Throwable var10) {
            this.handleRunFailure(context, var10, exceptionReporters, listeners);
            throw new IllegalStateException(var10);
        }

        try {
            listeners.running(context);
            return context;
        } catch (Throwable var9) {
            this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
            throw new IllegalStateException(var9);
        }
    }

终于看到一个比较不一样的方法了,这个方法里大致来看就是创建了ConfigurableApplicationContext实例然后返回,我们重点关注this.refreshContext(context),进入到这个方法里面

// SpringApplication.class
private void refreshContext(ConfigurableApplicationContext context) {
        this.refresh(context);
        if (this.registerShutdownHook) {
            try {
                context.registerShutdownHook();
            } catch (AccessControlException var3) {
                ;
            }
        }
    }

这里调用了this.refresh(context),我们在进入这个方法

// SpringApplication.class
protected void refresh(ApplicationContext applicationContext) {
        Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
        ((AbstractApplicationContext)applicationContext).refresh();
    }

这里((AbstractApplicationContext)applicationContext).refresh()又调用了refresh()方法,进入refresh()方法看看(这是咋们的重头戏)

// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }
        }
    }

代码到这先暂停一下,从Spring Boot的启动流程来看,显然Spring Boot启动以后使用的是ConfigurableApplicationContext这种ApplicationContext,那我们看看ClassPathXmlApplicationContext。早期Spring Boot未出现时,使用 ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("xxx")读取Spring配置文件来启动容器的方式经常被用到。我们直接找ClassPathXmlApplicationContext的构造方法

// ClassPathXmlApplicationContext.class
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();
        }
    }

这里也调用了refresh()方法,我们点进去看一下

// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }
        }
    }

显然不论是Spring Boot启动还是通过ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("xxx")启动容器,最终都进到AbstractApplicationContext的refresh()方法中,有兴趣的同学可以看看其他类型的ApplicationContext,比如说FileSystemXmlApplicationContext的构造方法同样都调用了这个方法,所以这是容器初始化最重要的方法,是Spring IOC容器初始化的整体逻辑,接下来我们已ClassPathXmlApplicationContext容器的初始化为例,从这个refresh()方法开始入手,
先写一下refresh()方法里面大致的行为

// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        // 加上锁,防止容器被重复创建
        synchronized(this.startupShutdownMonitor) {
            // 为刷新准备应用上下文
            this.prepareRefresh();
            // 这里是关键,在这刷新创建BeanFactory,并且读取Bean的配置信息,并且注册到Bean注册表(其实就是一个 beanName-> beanDefinition 的 map),但是Bean还没有被实例化
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor
            this.prepareBeanFactory(beanFactory);

            try {
                // 设置BeanFactory的后置处理器
                this.postProcessBeanFactory(beanFactory);
                // 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册Bean的后处理器,在Bean创建过程中调用
                this.registerBeanPostProcessors(beanFactory);
               //对上下文的消息源进行初始化
                this.initMessageSource();
                // 初始化上下文中的事件机制
                this.initApplicationEventMulticaster();
                // 初始化其他的特殊Bean
                this.onRefresh();
                // 检查监听Bean并且将这些Bean向容器注册
                this.registerListeners();
                // 初始化所有的 singleton beans(lazy-init除外),这个非常重要
                this.finishBeanFactoryInitialization(beanFactory);
                //  发布容器事件,结束refresh过程
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

到这我们先说这个refresh()方法中第一个重要的地方ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(), 进入this.obtainFreshBeanFactory()看一下

// AbstractApplicationContext.class
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        return this.getBeanFactory();
    }

其实就是关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等(但是Bean实例化没有在这完成),并且返回了BeanFactory,这里调用了 this.refreshBeanFactory(),继续进去看一下,进入AbstractRefreshableApplicationContext这个子类看具体实现

// AbstractRefreshableApplicationContext.class
protected final void refreshBeanFactory() throws BeansException {
        // 判断当前ApplicationContext是否已经有BeanFactory了,有的话销毁Bean实例和BeanFactory
        if (this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            // 初始化一个 DefaultListableBeanFactory
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            // BeanFactory设置序列化
            beanFactory.setSerializationId(this.getId());
            // 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
            this.customizeBeanFactory(beanFactory);
            // 使用BeanFactory加载Bean定义,就是BeanDefinition,这里是重点
            this.loadBeanDefinitions(beanFactory);
            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

跟我写的代码注释可以看出这段代码的大致流程就是,销毁已有的Bean实例和BeanFactory,然后创建一个新的DefaultListableBeanFactory,之后到this.loadBeanDefinitions(beanFactory)加载Bean定义,这是一个抽象方法,我们进到AbstractXmlApplicationContext这个类里面的loadBeanDefinitions(beanFactory)方法实现看一下

// AbstractXmlApplicationContext.class
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 给BeanFactory 实例化一个 XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        // 重点
        this.loadBeanDefinitions(beanDefinitionReader);
    }

比较简单,就是创建了一个XmlBeanDefinitionReader,给他设置了一些玩意,然后调用了重头戏this.loadBeanDefinitions(beanDefinitionReader),看这个方法

// AbstractXmlApplicationContext.class
  protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        Resource[] configResources = this.getConfigResources();
        if (configResources != null) {
            reader.loadBeanDefinitions(configResources);
        }
        String[] configLocations = this.getConfigLocations();
        if (configLocations != null) {
            reader.loadBeanDefinitions(configLocations);
        }
    }

我们进到reader.loadBeanDefinitions(configLocations)方法里看一下

// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
        Assert.notNull(locations, "Location array must not be null");
        int count = 0;
        String[] var3 = locations;
        int var4 = locations.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String location = var3[var5];
            count += this.loadBeanDefinitions(location);
        }
        return count;
    }

继续进 this.loadBeanDefinitions(location)

// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
        return this.loadBeanDefinitions(location, (Set)null);
    }

继续this.loadBeanDefinitions(location, (Set)null)

// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
        ResourceLoader resourceLoader = this.getResourceLoader();
        if (resourceLoader == null) {
            throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
        } else {
            int count;
            if (resourceLoader instanceof ResourcePatternResolver) {
                try {
                    Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
                    count = this.loadBeanDefinitions(resources);
                    if (actualResources != null) {
                        Collections.addAll(actualResources, resources);
                    }

                    if (this.logger.isTraceEnabled()) {
                        this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
                    }

                    return count;
                } catch (IOException var6) {
                    throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
                }
            } else {
                Resource resource = resourceLoader.getResource(location);
                count = this.loadBeanDefinitions((Resource)resource);
                if (actualResources != null) {
                    actualResources.add(resource);
                }

                if (this.logger.isTraceEnabled()) {
                    this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
                }

                return count;
            }
        }
    }

这里咋们还是关心count = this.loadBeanDefinitions(resources)和count = this.loadBeanDefinitions((Resource)resource),进到XmlBeanDefinitionReader的实现里面

// XmlBeanDefinitionReader.class
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        return this.loadBeanDefinitions(new EncodedResource(resource));
    }

继续进入loadBeanDefinitions(new EncodedResource(resource))

// XmlBeanDefinitionReader.class
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
        Assert.notNull(encodedResource, "EncodedResource must not be null");
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Loading XML bean definitions from " + encodedResource);
        }

        Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
        if (currentResources == null) {
            currentResources = new HashSet(4);
            this.resourcesCurrentlyBeingLoaded.set(currentResources);
        }

        if (!((Set)currentResources).add(encodedResource)) {
            throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
        } else {
            int var5;
            try {
                InputStream inputStream = encodedResource.getResource().getInputStream();

                try {
                    InputSource inputSource = new InputSource(inputStream);
                    if (encodedResource.getEncoding() != null) {
                        inputSource.setEncoding(encodedResource.getEncoding());
                    }

                    var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
                } finally {
                    inputStream.close();
                }
            } catch (IOException var15) {
                throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
            } finally {
                ((Set)currentResources).remove(encodedResource);
                if (((Set)currentResources).isEmpty()) {
                    this.resourcesCurrentlyBeingLoaded.remove();
                }

            }

            return var5;
        }
    }

我们关注var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource()),进入doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法

// XmlBeanDefinitionReader.class
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
        try {
            Document doc = this.doLoadDocument(inputSource, resource);
            int count = this.registerBeanDefinitions(doc, resource);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Loaded " + count + " bean definitions from " + resource);
            }

            return count;
        } catch (BeanDefinitionStoreException var5) {
            throw var5;
        } catch (SAXParseException var6) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
        } catch (SAXException var7) {
            throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
        } catch (ParserConfigurationException var8) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
        } catch (IOException var9) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
        } catch (Throwable var10) {
            throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
        }
    }

这里可以看出方法里创建了一个Document并且进到并且通过this.registerBeanDefinitions(doc, resource)把Bean注册到容器,进入这个方法

// XmlBeanDefinitionReader.class
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
        int countBefore = this.getRegistry().getBeanDefinitionCount();
        documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
        return this.getRegistry().getBeanDefinitionCount() - countBefore;
    }

这里创建BeanDefinitionDocumentReader并且调用documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource))把Bean注册进容器,进这个方法的实现

// DefaultBeanDefinitionDocumentReader.class
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
        this.readerContext = readerContext;
        this.doRegisterBeanDefinitions(doc.getDocumentElement());
    }

继续进this.doRegisterBeanDefinitions(doc.getDocumentElement())

// DefaultBeanDefinitionDocumentReader.class
protected void doRegisterBeanDefinitions(Element root) {
        BeanDefinitionParserDelegate parent = this.delegate;
        this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
        if (this.delegate.isDefaultNamespace(root)) {
            String profileSpec = root.getAttribute("profile");
            if (StringUtils.hasText(profileSpec)) {
                String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
                if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                    if (this.logger.isDebugEnabled()) {
                        this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
                    }

                    return;
                }
            }
        }

        this.preProcessXml(root);
        //   重点
        this.parseBeanDefinitions(root, this.delegate);
        this.postProcessXml(root);
        this.delegate = parent;
    }

进去看

// DefaultBeanDefinitionDocumentReader.class
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)) {
                        this.parseDefaultElement(ele, delegate);
                    } else {
                        delegate.parseCustomElement(ele);
                    }
                }
            }
        } else {
            delegate.parseCustomElement(root);
        }

    }

this.parseDefaultElement(ele, delegate)解析default namespace下面的几个元素,进去看一下

// DefaultBeanDefinitionDocumentReader.class
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
        if (delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        } else if (delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        } else if (delegate.nodeNameEquals(ele, "bean")) {
            this.processBeanDefinition(ele, delegate);
        } else if (delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

    }

分别解析四种xml里面的标签, <import />、<alias />、<bean />、<beans />,
以<bean />为例来看,进this.processBeanDefinition(ele, delegate)

// DefaultBeanDefinitionDocumentReader.class
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);

            try {
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
            } catch (BeanDefinitionStoreException var5) {
                this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
            }

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

    }

BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele)把xml文件中提取Bean信息实例化为BeanDefinition封装到BeanDefinitionHolder里面,BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry())把bdHolder里面的Bean定义注册到容器,最后this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder))执行容器通知,我们看看BeanDefinitionReaderUtils.registerBeanDefinition

// BeanDefinitionReaderUtils.class
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        String beanName = definitionHolder.getBeanName();
        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);
            }
        }
    }

先从definitionHolder里面取出beanName,然后取出对应的BeanDefinition, registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
把beanName和对应的BeanDefinition注册,最后在看一下registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())这个方法里面

// DefaultListableBeanFactory.class
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 var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }

        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }

            if (existingDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (!beanDefinition.equals(existingDefinition)) {
                if (this.logger.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isTraceEnabled()) {
                this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
            }

            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                Map var4 = this.beanDefinitionMap;
                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;
                    this.removeManualSingletonName(beanName);
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }

到这已经到把Bean信息注册到容器的最后一步,看this.beanDefinitionMap.put(beanName, beanDefinition),其实就是把beanName和beanDefinition作为一对键值对存储到beanDefinitionMap里面。
经过漫长的过程,到这已经完成了创建BeanFactory和生成BeanDefinition,但是还没有完成Bean实例化和依赖构建。

Bean实例化和依赖构建

上文已经走到了创建创建BeanFactory和生成BeanDefinition,就是创建了容器和注册了Bean定义,接下来我们研究Bean实例的初始化和Bean之间的依赖关系是如何构建的
重新回到refresh()方法中看一下

// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
        Object var1 = this.startupShutdownMonitor;
        // 加上锁,防止容器被重复创建
        synchronized(this.startupShutdownMonitor) {
            // 为刷新准备应用上下文
            this.prepareRefresh();
            // 这里是关键,在这刷新创建BeanFactory,并且读取Bean的配置信息,并且注册到Bean注册表(其实就是一个 beanName-> beanDefinition 的 map),但是Bean还没有被实例化
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            //设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor
            this.prepareBeanFactory(beanFactory);

            try {
                // 设置BeanFactory的后置处理器
                this.postProcessBeanFactory(beanFactory);
                // 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 注册Bean的后处理器,在Bean创建过程中调用
                this.registerBeanPostProcessors(beanFactory);
               //对上下文的消息源进行初始化
                this.initMessageSource();
                // 初始化上下文中的事件机制
                this.initApplicationEventMulticaster();
                // 初始化其他的特殊Bean
                this.onRefresh();
                // 检查监听Bean并且将这些Bean向容器注册
                this.registerListeners();
                // 初始化所有的 singleton beans(lazy-init除外),这个非常重要
                this.finishBeanFactoryInitialization(beanFactory);
                //  发布容器事件,结束refresh过程
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }
        }
    }

上文我们走完了this.obtainFreshBeanFactory()这个方法,Bean的实例化和依赖构建则是在this.finishBeanFactoryInitialization(beanFactory)方法里完成,如果没有设置懒加载,这里将会完成所有singleton bean(单例)的初始化。我们进这个方法

// AbstractApplicationContext.class
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver((strVal) -> {
                return this.getEnvironment().resolvePlaceholders(strVal);
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

我们直接看最后一个方法beanFactory.preInstantiateSingletons()

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

        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 {
                                if (!var2.hasNext()) {
                                    var2 = beanNames.iterator();

                                    while(var2.hasNext()) {
                                        beanName = (String)var2.next();
                                        Object singletonInstance = this.getSingleton(beanName);
                                        if (singletonInstance instanceof SmartInitializingSingleton) {
                                            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                            if (System.getSecurityManager() != null) {
                                                AccessController.doPrivileged(() -> {
                                                    smartSingleton.afterSingletonsInstantiated();
                                                    return null;
                                                }, this.getAccessControlContext());
                                            } else {
                                                smartSingleton.afterSingletonsInstantiated();
                                            }
                                        }
                                    }

                                    return;
                                }

                                beanName = (String)var2.next();
                                bd = this.getMergedLocalBeanDefinition(beanName);
                            } while(bd.isAbstract());
                        } while(!bd.isSingleton());
                    } while(bd.isLazyInit());

                    if (this.isFactoryBean(beanName)) {
                        bean = this.getBean("&" + beanName);
                        break;
                    }

                    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);
            }
        }
    }

这里不同的Spring版本可能代码不太一样,其实就是排除懒加载和abstract的bean,把所有非懒加载在和abstract的singleton bean实例化。代码通过this.getBean(beanName)就可以完成实例化,我们看这个方法,里面调用了this.doGetBean(name, (Class)null, (Object[])null, false),我们直接看doGetBean()方法

// AbstractBeanFactory.class
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
        String beanName = this.transformedBeanName(name);
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        if (sharedInstance != null && args == null) {
            if (this.logger.isTraceEnabled()) {
                if (this.isSingletonCurrentlyInCreation(beanName)) {
                    this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }

            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {
            if (this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                String nameToLookup = this.originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
                }

                if (args != null) {
                    return parentBeanFactory.getBean(nameToLookup, args);
                }

                if (requiredType != null) {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }

                return parentBeanFactory.getBean(nameToLookup);
            }

            if (!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }

            try {
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                this.checkMergedBeanDefinition(mbd, beanName, args);
                String[] dependsOn = mbd.getDependsOn();
                String[] var11;
                if (dependsOn != null) {
                    var11 = dependsOn;
                    int var12 = dependsOn.length;

                    for(int var13 = 0; var13 < var12; ++var13) {
                        String dep = var11[var13];
                        if (this.isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }

                        this.registerDependentBean(dep, beanName);

                        try {
                            this.getBean(dep);
                        } catch (NoSuchBeanDefinitionException var24) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                        }
                    }
                }

                if (mbd.isSingleton()) {
                    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);
                } else if (mbd.isPrototype()) {
                    var11 = null;

                    Object prototypeInstance;
                    try {
                        this.beforePrototypeCreation(beanName);
                        prototypeInstance = this.createBean(beanName, mbd, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }

                    bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } else {
                    String scopeName = mbd.getScope();
                    Scope 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, () -> {
                            this.beforePrototypeCreation(beanName);

                            Object var4;
                            try {
                                var4 = this.createBean(beanName, mbd, args);
                            } finally {
                                this.afterPrototypeCreation(beanName);
                            }

                            return var4;
                        });
                        bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    } catch (IllegalStateException var23) {
                        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", var23);
                    }
                }
            } catch (BeansException var26) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var26;
            }
        }

先看这部分代码

                String[] dependsOn = mbd.getDependsOn();
                String[] var11;
                //  遍历依赖
                if (dependsOn != null) {
                    var11 = dependsOn;
                    int var12 = dependsOn.length;

                    for(int var13 = 0; var13 < var12; ++var13) {
                        String dep = var11[var13];
                        if (this.isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }

                        this.registerDependentBean(dep, beanName);

                        try {
                            // 先实例化依赖,递归
                            this.getBean(dep);
                        } catch (NoSuchBeanDefinitionException var24) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
                        }
                    }
                }

这段代码获取了bean的依赖,遍历它的依赖,并且this.getBean(dep)先实例化依赖,就这样递归直到没有依赖为止,进入下面这段代码

if (mbd.isSingleton()) {
                    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);
                }

这段代码调用了this.createBean(beanName, mbd, args),我们进这个方法

// AbstractAutowireCapableBeanFactory.class
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Creating instance of bean '" + beanName + "'");
        }

        RootBeanDefinition mbdToUse = mbd;
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

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

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

        try {
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Finished creating instance of bean '" + beanName + "'");
            }

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            throw var7;
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
        }
    }

进beanInstance = this.doCreateBean(beanName, mbdToUse, args)看

// AbstractAutowireCapableBeanFactory.class
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        Object var7 = mbd.postProcessingLock;
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    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");
            }

            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }

        Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = this.getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                } else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if (!this.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.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

这个方法的内容相当多重点在于:

  1. instanceWrapper = this.createBeanInstance(beanName, mbd, args);完成Bean实例化
  2. this.populateBean(beanName, mbd, instanceWrapper)完成依赖注入

我们先看第一个方法

// AbstractAutowireCapableBeanFactory.class
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        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());
        } else {
            Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName);
            } else if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            } else {
                boolean resolved = false;
                boolean autowireNecessary = false;
                if (args == null) {
                    Object var8 = mbd.constructorArgumentLock;
                    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 {
                    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);
                    }
                }
            }
        }
    }

进这个this.instantiateBean(beanName, mbd)方法看

// AbstractAutowireCapableBeanFactory.class
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(() -> {
                    return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);
                }, this.getAccessControlContext());
            } else {
                beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
            }

            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            this.initBeanWrapper(bw);
            return bw;
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
        }
    }

这里通过beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this)进行bean实例化,进这个方法

// SimpleInstantiationStrategy.class
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        if (!bd.hasMethodOverrides()) {
            Object var5 = bd.constructorArgumentLock;
            Constructor constructorToUse;
            synchronized(bd.constructorArgumentLock) {
                constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    Class<?> clazz = bd.getBeanClass();
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }

                    try {
                        if (System.getSecurityManager() != null) {
                            clazz.getClass();
                            constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
                                return clazz.getDeclaredConstructor();
                            });
                        } else {
                            constructorToUse = clazz.getDeclaredConstructor();
                        }

                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    } catch (Throwable var9) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", var9);
                    }
                }
            }

            return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
        } else {
            return this.instantiateWithMethodInjection(bd, beanName, owner);
        }
    }

这里边调用了BeanUtils.instantiateClass(constructorToUse, new Object[0])利用构造器创建了实例,到这算是完成Bean的实例化了
我们刚刚说到的两行代码:

  1. instanceWrapper = this.createBeanInstance(beanName, mbd, args)完成Bean实例化
  2. this.populateBean(beanName, mbd, instanceWrapper)完成依赖注入

我们接下来看第二行,进入第二个方法

// AbstractAutowireCapableBeanFactory.class
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 {
            boolean continueWithPropertyPopulation = true;
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var5 = this.getBeanPostProcessors().iterator();

                while(var5.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }

            if (continueWithPropertyPopulation) {
                PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
                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;
                }

                boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
                boolean needsDepCheck = mbd.getDependencyCheck() != 0;
                PropertyDescriptor[] filteredPds = null;
                if (hasInstAwareBpps) {
                    if (pvs == null) {
                        pvs = mbd.getPropertyValues();
                    }

                    Iterator var10 = this.getBeanPostProcessors().iterator();

                    while(var10.hasNext()) {
                        BeanPostProcessor bp = (BeanPostProcessor)var10.next();
                        if (bp instanceof InstantiationAwareBeanPostProcessor) {
                            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                            PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                            if (pvsToUse == null) {
                                if (filteredPds == null) {
                                    filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                                }

                                pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                                if (pvsToUse == null) {
                                    return;
                                }
                            }

                            pvs = pvsToUse;
                        }
                    }
                }

                if (needsDepCheck) {
                    if (filteredPds == null) {
                        filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }

                    this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
                }

                if (pvs != null) {
                    this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
                }

            }
        }
    }

PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null获取到该bean的所有属性,通过this.autowireByName(beanName, mbd, bw, newPvs)和this.autowireByType(beanName, mbd, bw, newPvs)进行依赖装配,最后this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs)配置bean实例属性值。

走到这就完成了Spring IOC容器初始化流程,处理了Bean实例的初始化和Bean之间构建依赖关系


总结

流本文为阐述Spring IOC原理,先脱离Spring介绍了IOC思想原理,然后深入Spring IOC容器分别阐述了:

  1. Spring IOC容器的工作机制
  2. Spring IOC核心接口
  3. 深入Spring IOC源码解读Spring IOC容器初始流程

整个Spring IOC容器初始流程源码真的挺难啃下来的,需要花点时间消化,总结一下Spring IOC容器初始流程基本如下:

  1. 创建BeanFactory
  2. 加载Bean信息,注册BeanDefinition到BeanFactory
  3. 通过BeanFactory的BeanDefinition注册信息实例化Bean实例
  4. 通过BeanFactory的BeanDefinition注册信息构建Bean之间依赖关系
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342