Spring源码解析一 创建bean工厂 加载bean定义

Spring 最重要的概念是 IOC 和 AOP,而他们究竟是什么,我一步一步来解开Spring的神秘面纱。

版本 5.1.X

引言

     BeanFactory 简介

       首先说明,作者这里说的是beanFactory而不是FactoryBean,这两个名字是颠倒的,但是功能是完全不一样的,不了解的可以参考我另外一篇文章。https://mp-new.csdn.net/mp_blog/creation/editor/117602060

       beanFactory 从名字上理解,是Spring当中的工厂,能够去生产和获取我们的对象 。我们来看一下BeanFactory接口的结构图:

 


通过这个结构图我们就知道DefaultListableBeanFactory是一个功能最全的类。

 

先看一下Spring项目结构图,千万别被这些多给吓到,后面我们会一一分析。

 

项目启动

1、先看一下启动结构

其中AppConfig代码如下:

@Component
@ComponentScan(value = "my.study.spring.context")
public class AppConfig {
}

来看看我们的启动方法:

你没有看错,就只有一行代码,在这一行代码里完成了Spring的整个操作,实例化Spring容器,扫描类,解析类,实例化beanDefinition等等。

为了方便查看,我将会用图来表示,现在就相当于有了一个Spring环境:

我们来看看AnnotationConfigApplicationContext 构造方法里执行了什么操作。

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		//如果有父类会先调用父类的
		this();
		register(componentClasses);
		refresh();
	}

从AnnotationConfigApplicationContext的构造方法里执行的代码分为3步

  1. 调用父类的构造方法:

       

AnnotationConfigApplicationContext继承了GenericApplicationContext,所以说应该先看

GenericApplicationContext类的构造方法,如下图所示:

在GenericApplicationContext的构造方法里,new 了一个叫做,DefaultListableBeanFactory的类,就是beanFactory里功能最全的一个类。

我们来看看这个类里都定义了什么:

可以看到这里定义了这么多的属性,我把主要的记录下来,如图所示:

2、AnnotationConfigApplicationContext自身的构造方法

AnnotationConfigApplicationContext无惨构造器,主要是注册了6个bean到DefaultListableBeanFactory,这6个bean是Spring自带的。我们先来看看
AnnotatedBeanDefinitionReader这个类做了什么,点开它。

需要注意的是:

this.reader = new AnnotatedBeanDefinitionReader(this);

这个方法的所在类是AnnotationConfigApplicationContext,这里传的是this,

而到了AnnotatedBeanDefinitionReader类的构造方法里

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
   this(registry, getOrCreateEnvironment(registry));
}

用的却是BeanDefinitionRegistry来接受参数,这一现象说明了,AnnotationConfigApplicationContext与BeanDefinitionRegistry是一样的,BeanDefinitionRegistry也是Spring的一个环境,我们来修改图的信息:

我们接着往下看,点开这个this()方法:

this(registry, getOrCreateEnvironment(registry));

接着点开:

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

是一个空壳方法,接着看下一个方法

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
   registerAnnotationConfigProcessors(registry, null);
}

 

这个方法里主要是注册了6个bean

先获取了DefaultListableBeanFactory工厂,而后依次判断添加这几个bean.

怎么添加的呢?请注意这个方法:registerPostProcessor(registry, def, xxx);

 

我们看这个方法内部:registry.registerBeanDefinition(beanName, definition);

DefaultListableBeanFactory#registerBeanDefinition,是工厂类的方法,

这个方法里,主要是以下代码(无关代码做了删除)

 

走到这里,我们的beanDefinitionMap、beanDefinitionNames都有了相应的数据。

其中有一个bean很重要很重要,请记住它,我们后面说:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor

现在的结构图:

我们现在回到AnnotationConfigApplicationContext的无惨构造方法就讲完了

下面说说,AnnotationConfigApplicationContext的有参构造方法,

上面这个方法是从AnnotationConfigApplicationContext被创建时掉进来的

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

所以说,此时:componentClasses就是AppConfig,由于我们说完了this()方法,下面说

register(componentClasses);这个方法,让我们进入到这个方法里:

这个方法是一个空壳方法,里面调用了另外一个方法:

这里面循环遍历,componentClasses,此时只有一个AppConfig,我们看

registerBean()方法。

registerBean()方法,也是个空壳方法,呵、Spring啊!!! 我们看里面调用了:doRegisterBean()方法。

这里其实有一个面试题,就是如何把一个xxx.class变成一个beanDefinition,其中有一种方法就是直接通过BeanDefinition的构造方法转换,还有一种这里先不讨论。此时的

AnnotatedGenericBeanDefinition就是我们得到AppConfig类。我们接着往下看,处理作用域,bean名字等,最要还是最后一行代码。

 

我注释写的很明白,其实就是将Appconfig注册到BeanFactory中,我们来看是怎么注册的。

 

看上面的代码,就是通过

registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

将AppConfig注册到bean工厂的。这个方法熟悉不熟悉?没错,就是在注入那6个Springbean的时候调用的方法,这里也将AppConfig注册到Bean工厂。到此为此,BeanFactory里就有了7个对象。7对象中有一个是AppCoonfig,一个是ConfigurationClassPostProcessor(但是这个类在Spring里的名字是internalConfigurationAnnotationProcessor),剩余的5个是BeanPostProcessor后置处理器

 

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
   //如果有父类会先调用父类的
   this();
   register(componentClasses);
   refresh();
}

文章说到这里,AnnotationConfigApplicationContext的构造方法还剩一个refresh()就说完了,而refresh(),这个方法内容较多,我会另外写一篇文章专门写refresh()方法的内容。

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小tu豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值