SpringIOC 源码解析

SpringIOC 源码解析

本篇主要和大家一起来看看spring中ioc的源码,从bean的定义到初始化、实例化的过程。我们都说spring其实就是个HashMap,那么到底底层是怎么管理beans的呢,还有我们想知道为什么使用了注解[@Component]之后,spring就会自动将这个类加入到容器。在这篇文章我尽量去解答这个疑问,有错漏的请大家指正。

前言

工欲善其事必先利其器,如今做java的不可能跳过Spring,遇到什么困难都不要怕,勇敢的面对它。

在阅读本篇之前,我假定大家都有一定的spring基础,至少使用配置文件的方式搭建一个spring工程没有问题。本篇对应的spring版本是5.2.5.RELEASE,查看工具是IDEA。

SpringIOC其实要强调的就2个部分:

  • 读取配置,得到BeanDefinition
  • 实例化、初始化Bean

还有3个比较重要的接口,他们的名字都比较类似【spring的方法和类名是真的长,但是也是超级规范,见名知意】

  • BeanPostProcessor
  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor

这些单词我们在后面的源码中将会经常见到,大家一定要注意区分清楚。名称一旦看混了,就容易晕了。

准备

很多人其实还是比较想看源码的,但是又觉得无从下手,我们打断点应该从哪里开始呢?

任何java程序的入口一定是main方法,最简单的SpringBoot项目的主类不就是main方法嘛。当然我们这里不写main,我们写测试类。

先来一些基本代码,大家直接copy我的代码,然后运行出结果就好了。只是做个演示

pom引入spring-context包,junit包。

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.5.RELEASE</version>
    </dependency>
</dependencies>

我们看看context包的内容

image-20200409214352184

spring-context包以及包含了关键的几个:aop、beans、context、core、jcl、expression,这里jcl其实就是common-logging包,改了个名字。

创建几个基本的bean实现一些接口

public class MyBean implements InitializingBean, DisposableBean {
    
    @Override
    public void destroy() throws Exception {
        // bean销毁时调用此方法
        System.out.println("MyBean >>> destroy");
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
        // bean赋值时调用
        System.out.println("MyBean >>> afterPropertiesSet");
    }
}
public class MyBeanDefinitionRegistationPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanDefinitionRegistry >>> 当前 beans:" + registry.getBeanDefinitionNames().length);
    
        for (String beanDefinitionName : registry.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("----------");
    }
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanFactory >>> 当前 beans:" + beanFactory.getBeanDefinitionNames().length);
    }
}
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("MyBeanFactoryPostProcessor >>> postProcessBeanFactory >>> 当前有定义的 bean:" + beanFactory.getBeanDefinitionNames().length);
    }
}
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + " >>>  MyBeanPostProcessor  >>> Before 初始化 ");
        return bean;
    }
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(beanName + " >>>  MyBeanPostProcessor  >>> After 初始化 ");
        return bean;
    }
}
public class Red {
    private String color;
}

注意我们使用的是xml的方式配置bean,没有加注解。

下面定义一个spring的bean文件,beans.xml

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="top.ybq87.Red" id="red"/>

    <bean id="myBean" class="top.ybq87.MyBean"/>

    <bean class="top.ybq87.MyBeanDefinitionRegistationPostProcessor" id="myBeanDefinitionRegistationPostProcessor"/>

    <bean class="top.ybq87.MyBeanFactoryPostProcessor" id="myBeanFactoryPostProcessor"/>

    <bean class="top.ybq87.MyBeanPostProcessor" id="myBeanPostProcessor"/>

</beans>

然后编写一个测试方法

@Test
public void test() {
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:beans.xml");
    System.out.println("applicationContext:" + applicationContext);
    applicationContext.start();

    applicationContext.close();
}

这里获取的是ClassPathXmlApplicationContext,为了使用start方法和close方法,主要是测试bean的销毁。

执行测试方法后的打印:

MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanDefinitionRegistry >>> 当前 beans:5
red
myBean
myBeanDefinitionRegistationPostProcessor
myBeanFactoryPostProcessor
myBeanPostProcessor
----------
MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanFactory >>> 当前 beans:5
MyBeanFactoryPostProcessor >>> postProcessBeanFactory >>> 当前有定义的 bean:5
red >>>  MyBeanPostProcessor  >>> Before 初始化 
red >>>  MyBeanPostProcessor  >>> After 初始化 
myBean >>>  MyBeanPostProcessor  >>> Before 初始化 
MyBean >>> afterPropertiesSet
myBean >>>  MyBeanPostProcessor  >>> After 初始化 
applicationContext:org.springframework.context.support.ClassPathXmlApplicationContext@4fccd51b,...
MyBean >>> destroy

要开始看源码了,跟我做,一定要一遍看文章,一遍打开源码查看!

开始

debug进入之后,我们首先找到构造方法:

ClassPathXmlApplicationContext#138行

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

    super(parent);
    // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割),非重点
    setConfigLocations(configLocations);
    if (refresh) {
        // 重点方法
        // 为什么是 refresh(),而不是 init() 这种名字的方法。
        // 因为 ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建容器的,
        // refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。
        refresh();
    }
}

进入refresh()方法,使用IDEA快捷键command + t,选择AbstractApplicationContext。

image-20200409220300752

完整方法速览

AbstractApplicationContext#519行,因为我加了注释,所以行数可能不一定和大家一样。

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 刷新前的预处理工作.记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符.
        // 然后给出一个空的方法,交给子类实现, 子类去设置一些自定义的系统属性. 然后就没了.
        prepareRefresh();
        // 2. 重点讲解
        // 创建 BeanFactory 对象【已经实例化了BeanFactory】,将配置文件中定义的 bean 解析为 BeanDefinition 然后存储到 beanDefinitionMap中
        // 一个 bean 就是一个 BeanDefinition,目前为止 Bean 还没有初始化,只是将它们的定义信息获取到了。
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 3. 设置 BeanFactory 的一些属性. 添加几个BeanPostProcessor, 然后手动注册几个特殊的bean
        prepareBeanFactory(beanFactory);
        try {
            // 4. BeanFactory 准备工作完成后, 进行的后置处理工作. 方法是空的, 交给子类重写实现
            // 实现了 BeanFactoryPostProcessor 接口的类,会重写 postProcessorBeanFactory方法
            postProcessBeanFactory(beanFactory);
            // 5. 回调上一步 BeanFactoryPostProcessor 子类重写的postProcessBeanFactory方法
            // 执行了,执行了,执行了,但是还没有创建 bean
            invokeBeanFactoryPostProcessors(beanFactory);
            // 6. 注册 BeanPostProcessor 的实现类, 是 Bean 的后置处理器; 用来拦截 bean 的创建过程;
            // 还记得我在文章开头说的,3个比较相似的 PostProcessor 嘛?到这里就全部出现了。
            // 当前过程只是注册, 还没有执行
            // BeanPostProcessor 接口有2个 方法:
            // postProcessBeforeInitialization 和 postProcessAfterInitialization 分别会在 Bean 初始化之前和初始化之后得到执行
            // 注意,这里只是注册,只是注册,不执行,不执行,不执行
            registerBeanPostProcessors(beanFactory);
            // 7. 初始化 messageSource 组件 ; 负责 国际化, 消息绑定, 消息解析,不是重点
            initMessageSource();
            // 8. 初始化事件派发器, 
            initApplicationEventMulticaster();
            // 9. 此方法留给子类实现的, 在容器刷新的时候, 加入一些自定义方法. 这个方法我们在之后分析时还可能遇到
            onRefresh();
            // 10. 将监听器 ApplicationListener 注册进来
            registerListeners();
            // 11. 重点讲解,初始化 所有剩下的没有设置懒加载的单实例 Bean,到这里,才是真正的实例化 Bean
            // 注意这是说的初始化,Initialization:初始化,
            finishBeanFactoryInitialization(beanFactory);
            // 12. 最后完成
            finishRefresh();
        } catch (BeansException ex) {
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        } finally {
            resetCommonCaches();
        }
    }
}

上面的12个方法就是我们今天的全部内容部分,我将会对每个方法进行详细的讲解,当然如果你对某个部分感兴趣也可以直接跳到对应的编号。

1. prepareRefresh()

进入方法,这个不过多介绍,看注释就知道了。

protected void prepareRefresh() {
    // Switch to active.
    //记录容器启动时间
    this.startupDate = System.currentTimeMillis();
    // 容器是否关闭
    this.closed.set(false);
    // 容器是否激活
    this.active.set(true);
    // 1.1 初始化一些属性设置, 此方法是空的, 说明是里给子类来实现,从而加入一些自定义属性.
    initPropertySources();
    // 1.2 属性校验, 对系统环境或者是自定义属性进行校验.
    getEnvironment().validateRequiredProperties();
    // 1.3 然后new了一个list,用来保存容器中一些早期的事件, 在多播器可用时发布事件, 什么是事件,后面我们再看.
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

2. obtainFreshBeanFactory()

这个方法首先创建一个BeanFactory对象,然后进行 BeanDefinition 的解析和加载的,bean 的定义信息可以从xml配置文件来,也可以从注解的方式读取,或者从文件获取。经过这个方法之后,spring 就得到了所有的 BeanDefinition【bean的定义信息被封装为BeanDefinition对象,以后我们看到BeanDefinition就知道是bean的定义信息】,然后存储到 BeanFactory.beanDefinitionMap 属性中。这里出现了第一个ConcurrentHashMap。

查看obtainFreshBeanFactory()方法的源码

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 2.1 这个是具体创建的方法,由子类实现, 我们查看 AbstractApplicationContext 的几个子类
    // GenericApplicationContext 中的实现: 什么也没做,就是初始化了一个 DefaultListableBeanFactory beanFactory, 并设置了一个序列化的id
    // AbstractRefreshableApplicationContext 中的实现: 先看是否有BeanFactory了,有就销毁其中的bean,然后关闭BeanFactory;然后重新创建BeanFactory,初始化一些BeanDefinition
    refreshBeanFactory();
    // 2.2 上一步创建了 BeanFactory 之后,这里获得 BeanFactory 初始化对象[ConfigurableListableBeanFactory]类型 并返回
    return getBeanFactory();
}
2.1 refreshBeanFactory()

创建 BeanFactory 实例,我们快捷键command + t 看到有2个子类,其实他们都是创建一个 DefaultListableBeanFactory类型的BeanFactory对象。为什么是DefaultListableBeanfactory类型的呢?后面解答

AbstractRefreshableApplicationContext#124行方法中的定义

@Override
protected final void refreshBeanFactory() throws BeansException {
    // 是否已有 BeanFactory
    if (hasBeanFactory()) {
        // 销毁原有的 bean
        destroyBeans();
        // 关闭工厂
        closeBeanFactory();
    }
    try {
        // 创建新的 BeanFactory
        DefaultListableBeanFactory beanFactory = createBeanFactory();
        // 设置 序列化id
        beanFactory.setSerializationId(getId());
        // 设置 BeanFactory的2个配置属性, 是否允许bean覆盖,是否允许循环引用
        customizeBeanFactory(beanFactory);
        // 加载bean到BeanFactory中, 他是一个抽象方法, 交由子类实现. 可以加载一些我们自定义的 BeanDefinition
        // 看看他的几个子类: 是不是很熟悉, 假设我们写了一个 beans.xml, 里面定了很多的 <bean>,就是在这里进行解析的
        // FileSystemXmlApplicationContext: 从文件系统加载配置类
        // ClassPathXmlApplicationContext: 从classpath加载配置文件
        // XmlWebApplictaionContext:
        // AnnotationConfigWebApplicationContext: 以注解的方式加载配置的bean
        loadBeanDefinitions(beanFactory);
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

进入 loadBeanDefinitions(beanFactory)方法,我们选择XmlWebApplicationContext

2.1.1 loadBeanDefinitions

XmlWebApplicationContext#82行

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
    // Create a new XmlBeanDefinitionReader for the given BeanFactory.
    // 实例化一个 XmlBeanDefinitionReader
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

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

    // Allow a subclass to provide custom initialization of the reader,
    // then proceed with actually loading the bean definitions.
    // 初始化 XmlBeanDefinitionReader ,给子类重写用的
    initBeanDefinitionReader(beanDefinitionReader);
    // 重点部分
    loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        for (String configLocation : configLocations) {
            // 看这里
            reader.loadBeanDefinitions(configLocation);
        }
    }
}

AbstractBeanDefinitionReader#195行

@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
    return loadBeanDefinitions(location, null);
}

这个方法我们找到

int count = loadBeanDefinitions(resources);

然后

@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
    Assert.notNull(resources, "Resource array must not be null");
    int count = 0;
    // 每个文件是一个 resource
    for (Resource resource : resources) {
        // 这个关键方法进入,XmlBeanDefinitionReader 方法 309 行
        count += loadBeanDefinitions(resource);
    }
    return count;
}

我们在XmlBeanDefinitionReader#340行找到方法

return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
// 进入方法看到如下:我们以xml文档为例的,所以这里就是将xml文档解析为一个document
// 转为了 document 对象
Document doc = doLoadDocument(inputSource, resource);
// 继续分解
int count = registerBeanDefinitions(doc, resource);
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
    BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    int countBefore = getRegistry().getBeanDefinitionCount();
    // 看到了熟悉的 registerBeanDefinitions , 进入此方法
    documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    // 返回从当前配置文件加载了多少数量的 Bean
    return getRegistry().getBeanDefinitionCount() - countBefore;
}
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
    this.readerContext = readerContext;
    doRegisterBeanDefinitions(doc.getDocumentElement());
}

DefaultBeanDefinitionDocumentReader#121行进入方法定义

protected void doRegisterBeanDefinitions(Element root) {
    // BeanDefinitionParserDelegate 解析委托类, 负责解析 bean 的定义
    // 为什么定义为 parent, 因为 <beans> 节点里面 还可以定义 <beans> 的,所以这里可以递归
    BeanDefinitionParserDelegate parent = this.delegate;
    this.delegate = createDelegate(getReaderContext(), root, parent);
    if (this.delegate.isDefaultNamespace(root)) {
        // 获取 <beans profile="dev"> 这个里面的 profile 定义
        // 可以依据配置的环境加载不同的 bean , 不是当前环境的跳过不加载.
        // 比如设定当前是 test 环境 ;[springboot 可以通过 spring.profile.active:dev指定, 或者配置文件<beans profile="dev">],
        // 但是你定义的 <beans> 节点 profile = dev, 那么就不会去加载这个节点下的bean
        String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
        if (StringUtils.hasText(profileSpec)) {
            String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
                profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
            // We cannot use Profiles.of(...) since profile expressions are not supported
            // in XML config. See SPR-12458 for details.
            if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
                                 "] not matching: " + getReaderContext().getResource());
                }
                return;
            }
        }
    }

    // 钩子 模板方法吧
    preProcessXml(root);
    // 重点
    parseBeanDefinitions(root, this.delegate);
    // 钩子
    postProcessXml(root);

    this.delegate = parent;
}

查看parseBeanDefinitions方法

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // default节点: <import />、<alias />、<bean />、<beans />
    // spring 默认只有4个默认标签,其他的标签都属于自定义标签。比如<tx:annotation-driven/>、注解扫描标签<context:component-scan/>
    // 关于自定义标签的解析,我在文末的附录中讲解下。这里我们还是看默认的标签解析。
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                if (delegate.isDefaultNamespace(ele)) {
                    parseDefaultElement(ele, delegate);
                }
                else {
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        // 非默认节点进入此方法
        delegate.parseCustomElement(root);
    }
}

方法parseDefaultElement

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
    if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
        // import 标签处理
        importBeanDefinitionResource(ele);
    }
    else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
        processAliasRegistration(ele);
    }
    else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
        // <bean> 标签解析. 重点看这个
        processBeanDefinition(ele, delegate);
    }
    else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
        // recurse 递归调用,
        doRegisterBeanDefinitions(ele);
    }
}

processBeanDefinition方法

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    // 将 bean 节点解析,然后封装为 BeanDefinitionHolder 对象,这个对象我们以后还会经常见到的。
    BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    if (bdHolder != null) {
        // 自定义属性解析
        bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
        try {
            // 将 BeanDefinition 注册到 BeanFactory中,其实就是将bean的定义信息存放到map。
            BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
        }
        catch (BeanDefinitionStoreException ex) {
            getReaderContext().error("Failed to register bean definition with name '" +
                                     bdHolder.getBeanName() + "'", ele, ex);
        }
        // Send registration event.
        // bean 注册完毕,发送事件.
        getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    }
}

方法调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())

public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {
    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    // 看到了熟悉的东西了, 注册BeanDefinition,这个方法以后会经常见到。
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

如果大家感兴趣的话可以继续探究一下这个registry.registerBeanDefinition方法,她主要是判断bean是否允许覆盖,然后将 BeanDefinition 存入到 beanDefinitionMap 中。

到这里我们第一个重点部分就分解完了,其实说起来很简单,就是解析bean,然后变为 BeanDefinition对象存到BeanFactory中。

2.2 getBeanFactory()

将上一步创建的 BeanFactory 对象返回,最后得到了 ConfigurableListableBeanFactory类型的 BeanFactory 对象。至此我们的BeanFactory创建完毕。

3.prepareBeanFactory(beanFactory)

这个方法主要是给BeanFactory设置一些初始属性,加入了一个 BeanPostProcessor,然后加入了一些自动注入的属性。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 3.1 存放类加载器, 设置为加载当前applicationcontext类的类加载器.
    // BeanFactory 得到了 BeanDefinition, 那么为了将定义转为真正的实例,就需要类加载器了.
    beanFactory.setBeanClassLoader(getClassLoader());
    // 3.2 支持的表达式解析器
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // Configure the bean factory with context callbacks.
    // 3.3 添加一个 BeanPostProcessor 后置处理器, 不明白什么意思的先跳过这里,往下继续
    // 更多的 BeanPostProcessor 的注册是在 第 6.步
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    // 3.4 设置忽略的自动装配的Aware接口, 某个 Bean 依赖于下面的几个接口的实现类,在自动装配的时候忽略他们, Spring 会通过其他方式来处理这些依赖,这里也不是重点,
    // 参考: https://blog.csdn.net/qq_36951116/article/details/99587519
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // 3.4 设置可以用于自动装配的, 用户可以在自定义 Bean 中, 直接用过 @Autowired 注入下面的属性 不需要实现接口
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    // 3.5 添加 BeanPostProcessor [ApplicationListenerDetector], 注册 事件监听器,spring在各个重要节点都会发布一些事件,这里就是创建监听,当事件发生时进行处理。后面会看到的,当然也不是重点部分。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 3.6 添加 编译时的 AspectJ 支持, 此部分我们不讨论
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 3.7 给容器注册一些 默认组件.
    // Environment 环境属性 ConfigurableEnvironment
    // systemProperties 系统属性, 一个 map
    // systemEnvironment 系统环境变量, 一个 map
    // 可以直接使用 @Autowired 使用, 比如
    //     @Autowired
    //     Map<String, Object> systemProperties;
    // 就可以直接使用这个属性了。
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
}

先往下看

4. postProcessBeanFactory(beanFactory)

这个方法是留给子类进行拓展的,还记得我们上面写的几个测试方法嘛?

MyBeanDefinitionRegistationPostProcessorMyBeanFactoryPostProcessor,他们都实现了BeanFactoryPostProcessor接口【BeanDefinitionRegistryPostProcessor是继承了BeanFactoryPostProcessor接口】。

这里就是spring给用户提供的一个切入口,用户在 Bean 初始化之前可以进行一些自己的操作,比如注册一个自定义的 BeanDefinition。这个方法有个BeanFactory参数,各种bean的定义信息都可以获取,修改

我们上面的2个类就打印了一些BeanDefinition的信息,但是目前 Bean 其实都还没有实例化

5.invokeBeanFactoryPostProcessors(beanFactory)

专门负责回调上一步中被重写的 postProcessorBeanFactory方法。

BeanFactoryPostProcessor接口有一个子接口BeanDefinitionRegistryPostProcessor,这是spring官方大量使用的一个接口,专门用于动态注册Bean。此方法优先执行 BeanDefinitionRegistryPostProcessor 的 postProcessorBeanFactory方法,然后再执行BeanFactoryPostProcessor的postProcessorBeanFactory方法。

这点可以从我们的2个测试类的打印结果看到,大家仔细观察一下。我们先看源码

AbstractApplicationContext#774行

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 5.1 先去 getBeanFactoryPostProcessors() 获取所有的BeanFactoryPostProcessor, 进入 invokeBeanFactoryPostProcessors
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // aspectj相关,略过
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

我们看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法。是不是觉得有点眼熟,之前我们查看解析xml文件,将bean的定义转为BeanDefinition时,也接触到了一个BeanDefinitionParserDelegate,委托解析类。后面还会遇到他的,先有个印象。

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // 存放processor
    Set<String> processedBeans = new HashSet<>();

    // 判断 BeanFactory 是否是 BeanDefinitionRegistry 类型的
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

        // 循环 beanFactoryPostProcessors, 第一次进入时 beanFactoryPostProcessors.size == 0, 所以循环会跳过
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            } else {
                regularPostProcessors.add(postProcessor);
            }
        }

        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // 5.1.1 先拿到所有 实现了 BeanDefinitionRegistryPostProcessor 接口的 postprocessor
        String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 然后循环这些 PostProcessor
        for (String ppName : postProcessorNames) {
            // 得到实现了 PriorityOrdered 优先级接口的,
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        // 排序
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 回调 postProcessBeanDefinitionRegistry 方法,还记得我们定义的MyBeanDefinitionRegistationPostProcessor这个类嘛?
        // 这里就是回调它的重写的postProcessBeanDefinitionRegistry
        // invokeBeanDefinitionRegistryPostProcessors 方法查看下内容,其实就是做方法调用。
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        // 5.1.2 然后查询实现了 Ordered 接口的
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        registryProcessors.addAll(currentRegistryProcessors);
        // 回调 postProcessBeanDefinitionRegistry(registry)
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            // 5.1.3 最后, 找到没有实现任何优先级或者顺序接口的 BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 回调 postProcessBeanDefinitionRegistry(registry)
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }

        // 5.1.4 之前是执行的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法
        // 现在执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法.
        // 还记得BeanDefinitionRegistryPostProcessor接口有2个方法要重写嘛?上面只是调用了postProcessBeanDefinitionRegistry,但是还有一个postProcessBeanFactory方法,就在这里回调了。
        // 我们也可以从我们的测试代码的打印中看到这个现象,postProcessBeanDefinitionRegistry方法先被调用,之后才打印的postProcessBeanFactory
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    } else {
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    
    /* 上面只是回调了实现 BeanDefinitionRegistryPostProcessor 接口的方法,下面是回调实现了 BeanFactoryPostProcessor 接口的方法,其实流程是一样的。先按照有优先级的调用,然后是有order的,最后是没有任何优先级的。 */

    // 5.1.5 现在执行 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor 流程一样
    String[] postProcessorNames =
        beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (processedBeans.contains(ppName)) {
            // skip - already processed in first phase above
        } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        } else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 执行 postProcessBeanFactory 方法(时刻注意,这个方法是子类继承接口然后重写的接口的方法,执行这个方法只是做了些其他操作,还没有创建 bean)
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
}

这个方法看起来复杂,其实结构都很规整,就是调用第4步,用户重写的 BeanFactoryPostProcessor 的方法。有优先级的就按照优先级的调用。

目前我们的Bean还是没有初始化。

6. registerBeanPostProcessors(beanFactory)

注意,这里是注册,并没有执行,不执行,不执行,不执行,进入方法

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

我们又看到了熟悉的Delegate方法调用,

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 6.1 获取所有的 实现了 BeanPostProcessor 接口的实现类; 不同类型的 BeanPostProcessor 在bean的创建前后执行时机不一样.
    // BeanPostProcessor 的子接口: 大家可以自己去写方法实现一下这些结构,然后打印看看执行的时机。
    // DestructionAwareBeanPostProcessor : 用于定义在bean销毁前执行方法
    // InstantiationAwareBeanPostProcessor : (有不同的方法,)实例化bean之前,实例赋值之前,
    // MergedBeanDefinitionPostProcessor : 实例化Bean之后就执行这个,
    // SmartInstantiationAwareBeanPostProcessor :
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    // 略过
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    // 下面开始重点部分,不过我们之前在 5. 步的时候也看到了类似的结构,
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        } else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 后置处理器都有优先级 和 顺序
    // First, register the BeanPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    // 最后注册没有任何优先级的接口的 BeanPostProcessor
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 最终 注册 internalPostProcessors 中的 BeanPostProcessor
    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    // 最后 注册一个 ApplicationListenerDetector ,
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

7. initMessageSource()

8. initApplicationEventMulticaster()

进入方法

protected void initApplicationEventMulticaster() {
    // 8.1 获取所有的 BeanPostProcessor
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        // 8.2 获取 applicationEventMulticaster
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    } else {
        // 8.3 没有 applicationEventMulticaster 这个 ,那么就自动创建一个 SimpleApplicationEventMulticaster 类型的 ApplicationEventMulticaster
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        // 8.4 然后自动注册到 BeanFactory, 以后其他组件可以自动注入这个 applicationEventMulticaster 组件了.
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                         "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

当然不是重点,只是知道有个东西就好了。

9. onRefresh()

10. registerListeners()

注册监听器,监听器需要实现 ApplicationListener 接口,大家自己写一个实现类试试看。

protected void registerListeners() {
    // Register statically specified listeners first.
    // 10.1 从容器得到已有的 ApplicationListener 组件, 然后加入派发器
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 10.2 然后查询 ApplicationListener 接口的子类,加入到派发器
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let post-processors apply to them!
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }
    // 10.3 派发之前产生的事件, 
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

11. finishBeanFactoryInitialization(beanFactory)

下面是重点内容,到这里我们发现spring的结构真的写的太好了,一层一层的很清晰,之前看dubbo的源码时,就被它绕晕了。废话不多说,直接上源码

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 类型转换器服务, 很实用的,而且可能经常用到的功能。
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
        beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        // 最实用的场景就是用来将前端传递过来的参数,与Controller方法上的参数进行格式匹配.
        // 比如前端传递一个 String, 后端可以使用 Date 接收,那么就用到这个 conversionService
        // 这里不过多的展开,大家有兴趣的可以google下,手动滑稽
        beanFactory.setConversionService(
            beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // 值解析器, 方便的实现读取配置文件的属性,如果你不懂,就跳过
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 看到 LoadTimeWeaverAware 你第一眼应该想到的应该是 aspectj,不是我们的重点
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    // 停止使用 用于类型匹配的临时类加载器
    beanFactory.setTempClassLoader(null);

    // 冻结所有的 Bean 定义, 也就是说已经注册的 BeanDefinition 将不能被修改或者后置处理
    // 同时肯定不希望我正要实例化bean的时候,再注册进来一些bean定义啥的.不就没完没了了。
    beanFactory.freezeConfiguration();

    // 11.1 开始实例化剩下的单例bean
    beanFactory.preInstantiateSingletons();
}

11.1 beanFactory.preInstantiateSingletons()

依次进入方法

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

    // 11.1.1 得到所有的bean定义信息. beanDefinitionNames 保存了所有的 beanNames
    // 还记得 BeanDefinition 是在什么时候获取到的嘛?
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // 11.1.2 循环 beanNames, 进行初始化,创建对象.
    for (String beanName : beanNames) {
        // 得到定义信息, 合并父 Bean 中的配置, 因为 beans节点有一个参数 parent,这里不展开,大家感兴趣请google,不知道不影响后面的了解。
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 非抽象, 非懒加载, 且是单实例的. 才进行下面的解析。
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            // 11.1.3 判断这个bean是否是 实现了 FactoryBean 接口的bean, 如果是, 那么就调用 FactoryBean 的 getObject 得到 bean
            if (isFactoryBean(beanName)) {
                // 注意这里加了一个前缀 & , 还是记得如果要获得 FactoryBean 这个对象本身么
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                // 实现了 FactoryBean 接口的
                if (bean instanceof FactoryBean) {
                    final FactoryBean<?> factory = (FactoryBean<?>) bean;
                    boolean isEagerInit;
                    // 是否是 SmartFactoryBean 的实现
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                                                    ((SmartFactoryBean<?>) factory)::isEagerInit,
                                                                    getAccessControlContext());
                    } else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                       ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        // 第一次看到
                        getBean(beanName);
                    }
                }
            } else {
                // 11.1.4 不是 FactoryBean 的话, 调用 doGetBean 初始化对象,第二次看到
                // 这个getBean就是我们一般写测试方法时, applicationContext.getBean("xx"); 这个方法
                getBean(beanName);
            }
        }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        // 11.1.5 初始化 bean 之后, 调用这个后置处理器. 如果 bean 实现了 SmartInitializingSingleton 接口, 回调 afterSingletonsInstantiated
        // 这里就可以体会到 spring 多么的开放。
        if (singletonInstance instanceof SmartInitializingSingleton) {
            final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            } else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}
11.1.4 getBean(beanName)

上面的方法分析下来,getBean(beanName)这个方法最重要。

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

进入在AbstractBeanFactory#241行,返回一个已经实例化好的对象。

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

    // 获取到真正的 beanName, 因为 bean 的调用有2种:
    // factoryBean(前面有'&'符号的),
    // 还有使用别名来获取 bean 的,
    // 这个方法就是获取到最终的真实的 beanName
    final String beanName = transformedBeanName(name);
    // 方法返回值先定义出来
    Object bean;
    
    // 11.1.4.1 是否在缓存中已经有这个单实例 bean 实例,
    // 是从 singletonObjects 属性中获取, 她是一个 ConcurrentHashMap, 保存了所有的单实例对象, 看看,之所以说springioc就是个map,这就是证据啊,所有的单例bean都存在这个map中。
    // 在DefaultListableBeanFactory中有定义各种map,
    // private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    Object sharedInstance = getSingleton(beanName);

    // 如果已经有实例对象了, 直接取出返回
    if (sharedInstance != null && args == null) {
        if (logger.isTraceEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                             "' that is not fully initialized yet - a consequence of a circular reference");
            } else {
                logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        // 如果是一个普通的 Bean, 直接返回; 如果是 FactoryBean 的话, 就要调用 getObject 返回它创建的那个实例对象.
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    } else {
        // 11.1.4.2 缓存中拿不到, 开始创建对象流程
        if (isPrototypeCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }

        // 11.1.4.3 得到 BeanFactory, 因为对象都是从 BeanFactory 创建的
        BeanFactory parentBeanFactory = getParentBeanFactory();
        // 父工厂, springmvc 整合时才有父工厂,目前没有的. 略过
        if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
            // Not found -> check parent.
            String nameToLookup = originalBeanName(name);
            if (parentBeanFactory instanceof AbstractBeanFactory) {
                return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                    nameToLookup, requiredType, args, typeCheckOnly);
            } else if (args != null) {
                // Delegation to parent with explicit args.
                return (T) parentBeanFactory.getBean(nameToLookup, args);
            } else if (requiredType != null) {
                // No args -> delegate to standard getBean method.
                return parentBeanFactory.getBean(nameToLookup, requiredType);
            } else {
                return (T) parentBeanFactory.getBean(nameToLookup);
            }
        }

        if (!typeCheckOnly) {
            // 11.1.4.4 标记当前的 bean 已经创建
            markBeanAsCreated(beanName);
        }

        // ************* 开始创建 bean *************
        try {
            // 11.1.4.5 先得到 BeanDefinition bean 的定义信息
            final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
            checkMergedBeanDefinition(mbd, beanName, args);

            // 11.1.4.6 得到当前 bean 所依赖的其他 bean, 先创建这些依赖的 Bean,这里用到了递归
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
                for (String dep : dependsOn) {
                    // 是否循环依赖
                    if (isDependent(beanName, dep)) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                    }
                    // 注册依赖的 bean
                    registerDependentBean(dep, beanName);
                    try {
                        // 然后先创建这些依赖的 bean
                        getBean(dep);
                    } catch (NoSuchBeanDefinitionException ex) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                        "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                    }
                }
            }

            // 11.1.4.7 单实例的创建开始, 我们这里只讨论单例,多例的大家有空自己研究下,其实差不多。
            if (mbd.isSingleton()) {
                // 注意 getSingleton()这个方法,后面细看,先继续。
                sharedInstance = getSingleton(beanName, () -> {
                    try {
                        // 11.1.4.7.1 调用 createBean 方法 然后返回 这个 bean, 执行 getSingleton 方法.
                        // 将 bean 加入到 singletonObjects 缓存起来 .还加入到了 registeredSingletons,
                        return createBean(beanName, mbd, args);
                    } catch (BeansException ex) {
                        // 如果报错了,要删除构建信息。
                        destroySingleton(beanName);
                        throw ex;
                    }
                });
                bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
            }
            // 多实例的 bean 创建
            else if (mbd.isPrototype()) {
                // It's a prototype -> create a new instance.
                Object prototypeInstance = null;
                try {
                    beforePrototypeCreation(beanName);
                    prototypeInstance = createBean(beanName, mbd, args);
                } finally {
                    afterPrototypeCreation(beanName);
                }
                bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
            }
            // 如果不是 singleton 或者 prototype 的,那么就是自定义的scope, 比如 session, global-session, 这里就交给自定义的scope的应用方法实现
            // springmvc 中的 几个scope就是这么实现的.
            else {
                String scopeName = mbd.getScope();
                final Scope scope = this.scopes.get(scopeName);
                if (scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                }
                try {
                    Object scopedInstance = scope.get(beanName, () -> {
                        beforePrototypeCreation(beanName);
                        try {
                            return createBean(beanName, mbd, args);
                        } finally {
                            afterPrototypeCreation(beanName);
                        }
                    });
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                } catch (IllegalStateException ex) {
                    throw new BeanCreationException(beanName,
                                                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                                    "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                                    ex);
                }
            }
        } catch (BeansException ex) {
            cleanupAfterBeanCreationFailure(beanName);
            throw ex;
        }
    }

    // Check if required type matches the type of the actual bean instance.
    if (requiredType != null && !requiredType.isInstance(bean)) {
        try {
            T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
            if (convertedBean == null) {
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
            return convertedBean;
        } catch (TypeMismatchException ex) {
            if (logger.isTraceEnabled()) {
                logger.trace("Failed to convert bean '" + name + "' to required type '" +
                             ClassUtils.getQualifiedName(requiredType) + "'", ex);
            }
            throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
        }
    }
    return (T) bean;
}

我们来看看createBean(beanName, mbd, args)

11.1.4.7.1 createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    // 真正创建流程开始
    if (logger.isTraceEnabled()) {
        logger.trace("Creating instance of bean '" + beanName + "'");
    }
    // bean 的定义信息
    RootBeanDefinition mbdToUse = mbd;

    // 确保 BeanDefinition 中的 class 被加载,还记得我们之前看代码,有一个地方我们获取到了一个 ClassLoader ,我们不知道要这个ClassLoader干啥的,这里就是使用这个ClassLoader将用到的bean 的class文件装载到jvm
    // 有一些动态加载的bean的定义信息也确保能够加载。看不懂没关系,跳过先
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // Prepare method overrides.
    try {
        // 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />和 <replaced-method />
        mbdToUse.prepareMethodOverrides();
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                                               beanName, "Validation of method overrides failed", ex);
    }

    try {
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        // 11.1.4.7.2 给 InstantiationAwareBeanPostProcessor 一个返回代理而不是目标 bean 实例的机会。
        // 后面 aop 源码的时候再看.
        // 这个方法我们下面列出来,她就是执行了 bean 初始化的 前置通知 和 后置通知。还记得我们之前注册过的 BeanPostProcessor 嘛?就是在这里执行的。
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            // 是代理对象 , 直接返回 bean
            return bean;
        }
    } catch (Throwable ex) {
        throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                                        "BeanPostProcessor before instantiation of bean failed", ex);
    }

    try {
        //  11.1.4.7.3 如果不是代理对象, 那么就调用这个
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        // 11.1.4.7.17 bean 初始化完成返回
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

Object bean = resolveBeforeInstantiation(beanName, mbdToUse)查看

@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

看到applyBeanPostProcessorsBeforeInstantiationapplyBeanPostProcessorsAfterInitialization就知道了,她在bean的初始化前后分别回调了InstantiationAwareBeanPostProcessor的实现类的postProcessBeforeInstantiationpostProcessAfterInitialization方法。

代理对象在这个之后就返回了。但是我们要看的不是代理对象,继续

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

    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        //  11.1.4.7.4 创建实例 在这里 , 利用工厂方法 或者 无参构造函数, 创建 bean 的实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                // 11.1.4.7.5 bean 实例化了之后 又调用了一个 BeanDefinitionPostProcessor
                // 调用 实现了 MergedBeanDefinitionPostProcessor 接口的 postProcessMergedBeanDefinition 方法
                // Spring 对这个接口有几个默认的实现, 比如我们常用的 @Autowired 注解
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } catch (Throwable ex) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                                "Post-processing of merged bean definition failed", ex);
            }
            mbd.postProcessed = true;
        }
    }

    // 解决循环依赖问题
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                                      isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                         "' to allow for resolving potential circular references");
        }
        // 当正在创建 A 的时候, A 依赖 B, 但是 A 正在创建, 怎么给 B 呢? 这就是循环依赖
        // 此处就是解决循环依赖的问题, 将 a 作为一个 ObjectFactory 提前对外曝光, 让其他人能够找到它,虽然他还没有完全初始化完毕.
        // 那么 b 就可以在 cache中找到它, b 认为a已经创建了, 那么 b 就能够继续完成自己的初始化, 从而 a 也能够完成它的初始化.
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }

    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 11.1.4.7.6 为 Bean 实例属性赋值, 之前只是创建了bean,
        // 主要是调用一些后置处理器[如果有定义的话], 然后利用反射调用set方法给 bean 的属性赋值.
        // 这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
        populateBean(beanName, mbd, instanceWrapper);
        // 11.1.4.7.11 这里就是处理 bean 初始化完成后的各种回调
        // 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } catch (Throwable ex) {
        if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
            throw (BeanCreationException) ex;
        } else {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
        }
    }

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

    // Register bean as disposable.
    try {
        // 11.1.4.7.16 注册 销毁 方法, 容器关闭时,调用销毁bean的方法
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}

这里找出几个重点的

  • instanceWrapper = createBeanInstance(beanName, mbd, args):这里实例化了bean
  • applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName):执行一些回调
  • populateBean(beanName, mbd, instanceWrapper):上面只是初始化bean,这里为bean属性赋值,包括内部用到的依赖
  • exposedObject = initializeBean(beanName, exposedObject, mbd):bean 初始化完成后的各种回调

到这里终于看到了bean的实例化了。前面都是准备工作,包裹一些事件通知,前后回调。spring为我们开放了很多参与的入口。

先看 createBeanInstance 方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 得到 class 为初始化准备
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // 访问权限,跳过
    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());
    }

    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    if (mbd.getFactoryMethodName() != null) {
        // 利用工厂方法实例化, 注意不是 FactoryBean
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            // 构造函数依赖注入
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            // 实例化bean 无参构造函数
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    // 无参构造器
    return instantiateBean(beanName, mbd);
}

我们的重点是无参方法

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                                                         getInstantiationStrategy().instantiate(mbd, beanName, parent),
                                                         getAccessControlContext());
        } else {
            // 实例化bean
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        // 包装一下实例化的 bean
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    } catch (Throwable ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

我们看 getInstantiationStrategy().instantiate(mbd, beanName, parent)

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
        Constructor<?> constructorToUse;
        synchronized (bd.constructorArgumentLock) {
            constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
            if (constructorToUse == null) {
                final Class<?> clazz = bd.getBeanClass();
                if (clazz.isInterface()) {
                    throw new BeanInstantiationException(clazz, "Specified class is an interface");
                }
                try {
                    if (System.getSecurityManager() != null) {
                        constructorToUse = AccessController.doPrivileged(
                            (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                    }
                    else {
                        // 看到 getDeclaredConstructor 是不是很熟悉,反射啊
                        constructorToUse = clazz.getDeclaredConstructor();
                    }
                    bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                }
                catch (Throwable ex) {
                    throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                }
            }
        }
        // 到这里就是利用反射实例化bean了,
        return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
        // Must generate CGLIB subclass.
        // 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,cglib先不讨论
        return instantiateWithMethodInjection(bd, beanName, owner);
    }
}

以上我们不再深入,再下去就是反射的基本知识了

populateBean(beanName, mbd, instanceWrapper)

我们看属性赋值

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    if (bw == null) {
        if (mbd.hasPropertyValues()) {
            throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
        } else {
            // Skip property population phase for null instance.
            return;
        }
    }

    // 11.1.4.7.7 在赋值之前, 又一个 赋值的 后置处理器[如果有]. 看到 BeanPostProcessor 都已经麻木了吧。
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }

    // 11.1.4.7.8 得到属性
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
        // Add property values based on autowire by name if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
            autowireByName(beanName, mbd, bw, newPvs);
        }
        // Add property values based on autowire by type if applicable.
        if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            autowireByType(beanName, mbd, bw, newPvs);
        }
        pvs = newPvs;
    }

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

    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
        if (pvs == null) {
            pvs = mbd.getPropertyValues();
        }
        // // 11.1.4.7.9 然后得到所有的后置处理器, 再去处理一下,[此时属性还没有赋值]
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    // 对采用 @Autowired、@Value 注解的依赖进行设值
                    pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
    }
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }

    if (pvs != null) {
        // 11.1.4.7.10 最后才为属性赋值, 反射调用set方法
        applyPropertyValues(beanName, mbd, bw, pvs);
    }
}

经过上面我们知道这个方法就是调用一些赋值前的回调,然后赋值。

initializeBean(beanName, exposedObject, mbd)

spring在我们实例化bean之后,还可以对bean做些初始化的工作。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        // 11.1.4.7.12 处理 Aware 接口的方法,
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 11.1.4.7.13 然后再次调用一个 BeanPostProcessor ,在 bean 初始化之前的操作.
        // postProcessBeforeInitialization 方法
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 11.1.4.7.14 执行初始化方法.
        // 是否实现了 InitializingBean 接口. 还记得我们写的测试 MyBean 嘛?
        invokeInitMethods(beanName, wrappedBean, mbd);
    } catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 11.1.4.7.15 又来了一个 BeanPostProcessor 在初始化之后调用的方法.
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    // 整个初始化完成
    return wrappedBean;
}

这个方法不难理解,执行一些bean初始化操作。重点说下 Aware

Spring中提供了一些Aware接口,比如BeanFactoryAware,ApplicationContextAware,ResourceLoaderAware,ServletContextAware等,实现这些Aware接口的bean在被初始化后,可以取得一些相对应的资源,例如实现BeanFactoryAware的bean在初始化之后,Spring容器将会注入BeanFactory实例,而实现ApplicationContextAware的bean,在bean被初始化后,将会被注入ApplicationContext实例等

关于 invokeInitMethods(beanName, wrappedBean, mbd)

我们自定义的MyBean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑,打印。
init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet先执行,而init-method后执行。
在invokeInitMethods方法中就实现了这两个步骤的初始化调用,详细的调用逻辑大家自己看源码了,就不列出占用篇幅。

12. finishRefresh()

这个方法完成收尾工作

protected void finishRefresh() {
    // 去除缓存
    clearResourceCaches();

    // 12.1 初始化和生命周期有关的后置处理器
    // 可以实现一个 LifecycleProcessor 接口, 在容器的生命周期关键点打印数据.
    initLifecycleProcessor();

    // 12.2 拿到了前面定义的生命周期(BeanFactory)处理器, 回调 onRefresh() 方法,记得这个方法不
    getLifecycleProcessor().onRefresh();

    // 12.3 发布容器刷新完成事件 ContextRefreshedEvent,
    publishEvent(new ContextRefreshedEvent(this));

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

好了,到此为止BeanFactory已经完成了实例化并且初始化完毕。我们的ioc容器也就创建完成。

总结

img

附录

自定义标签的解析,顺带说明注解@Component的解析

在上面我们解析BeanDefinition的时候,在DefaultBeanDefinitionDocumentReader中方法doRegisterBeanDefinitions时,遇到了

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
    // default节点: <import />、<alias />、<bean />、<beans />
    if (delegate.isDefaultNamespace(root)) {
        NodeList nl = root.getChildNodes();
        for (int i = 0; i < nl.getLength(); i++) {
            Node node = nl.item(i);
            if (node instanceof Element) {
                Element ele = (Element) node;
                if (delegate.isDefaultNamespace(ele)) {
                    parseDefaultElement(ele, delegate);
                }
                else {
                    // @Component,这个就是自定义标签对应的注解,
                    // @Service,@Controller,@Repository这些注解都被@Component注解所以,他们都是等价的,也都会被扫到
                    delegate.parseCustomElement(ele);
                }
            }
        }
    }
    else {
        // 非默认节点进入此方法
        delegate.parseCustomElement(root);
    }
}

我们重点看 delegate.parseCustomElement(ele);自定义标签的解析,我们通过这个方法找到了下面的方法

public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
    // 通过xml的节点获取到对应的 命名空间URI【比如context的http://www.springframework.org/schema/context】
    String namespaceUri = getNamespaceURI(ele);
    if (namespaceUri == null) {
        return null;
    }
    // 通过 命名空间 获取 NamespaceHandler, 先进入这个 resolve 方法
    NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
    if (handler == null) {
        error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
        return null;
    }
    // 开始解析自定义标签
    return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}

很奇怪啊,这里的命名空间是什么呢?大家还记得xml配置文件中的配置吗?比如我们配置自动扫包的时候需要加一些网址,很多人不明白这个网址到底有啥意思,这里你就知道了。回顾一下定义

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

我们先看resolve方法

public NamespaceHandler resolve(String namespaceUri) {
    // 获取所有一级配置的 handler,getHandlerMappings()这个方法获取到所有的命名空间和对应的uri的一个map
    // 比如 <context:component-scan base-package="top.ybq87"/> 这个标签对应的 
    // uri是:http://www.springframework.org/schema/context
    // getHandlerMappings()方法有个小坑,我们正常debug进入时发现handlerMappings已经被初始化了,但是我们没有找到任何地方调用它的,除了一个 toString()方法,所以就是因为这个toString的问题导致handlerMappings提前初始化。
    // 具体参考: https://www.zhihu.com/question/61890921
    Map<String, Object> handlerMappings = getHandlerMappings();
    // 然后通过 uri 得到对应的 className :org.springframework.context.config.ContextNamespaceHandler
    // 这个 handlerMappings 是什么时候初始化的呢
    Object handlerOrClassName = handlerMappings.get(namespaceUri);
    if (handlerOrClassName == null) {
        return null;
    } else if (handlerOrClassName instanceof NamespaceHandler) {
        return (NamespaceHandler) handlerOrClassName;
    } else {
        String className = (String) handlerOrClassName;
        try {
            // 既然我们得到了 className, 就能够通过反射加载这个类了
            Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
            if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
                throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
                                             "] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
            }
            // 然后实例化对象
            NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
            // 调用它的 init() 方法, 这个很重要。
            namespaceHandler.init();
            // 放入缓存
            handlerMappings.put(namespaceUri, namespaceHandler);
            return namespaceHandler;
        } catch (ClassNotFoundException ex) {
            throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
                                         "] for namespace [" + namespaceUri + "]", ex);
        } catch (LinkageError err) {
            throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
                                         className + "] for namespace [" + namespaceUri + "]", err);
        }
    }
}

我们使用的是xml文件配置,得到的namespaceuri = org.springframework.context.config.ContextNamespaceHandler,那我们直接索索下这个类的定义, 然后看init()方法

public class ContextNamespaceHandler extends NamespaceHandlerSupport {

	@Override
	public void init() {
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}

发现这里只有一个init()方法,看到了很多熟悉的标签,我们查看component-scan。会先创建一个 parser,然后注册进NamespaceHandlerSupport的parsers中。这个在之后的解析中用到,先记住这个。

退出resolve方法。handler.parse进入

public BeanDefinition parse(Element element, ParserContext parserContext) {
    BeanDefinitionParser parser = findParserForElement(element, parserContext);
    // 回调解析方法
    return (parser != null ? parser.parse(element, parserContext) : null);
}

看到后面的执行解析,这就是回调了我们上面实例化的解析方法。我们查看parser.parse的时候,发现一长串解析方法。选择

ComponentScanBeanDefinitionParser就会调用它的解析方法。

public BeanDefinition parse(Element element, ParserContext parserContext) {
    String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
    basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
    String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
                                                              ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);

    // Actually scan for bean definitions and register them.
    // 定义一个扫描器,用来扫包
    ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
    // 开始扫描, 然后将扫到的 bean 的定义信息 BeanDefinition 注入到 BeanFactory
    // 扫包的时候 实际上,是把所有包下的class文件都扫描了的,并且利用asm技术读取java字节码并转化为MetadataReader中的AnnotationMetadataReadingVisitor结构
    // 扫描器采用asm技术扫描java字节码文件,即.class文件。扫描时是扫描指定包下的全部class文件,转换成指定的MetadataReader结构后,再去判断是否符合扫描规则,符合的才加入候选bean中,并注册到容器中。
    Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
    registerComponents(parserContext.getReaderContext(), beanDefinitions, element);

    return null;
}

这个就不展开了,太多了,简单说下,这个方法就是得到了我们要扫描的包路径,然后迭代得到所有的file,然后去掉一些filter过滤的文件,封装为FileSystemResource,得到bean的定义信息,注册到 BeanFactory ,最后进行一些消息通知。

注解处理器会在bean实例化的时候被回调,因为他们都是 BeanPostProcessor 的子类。

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值