Analysis of the initial construction of the spring factory from the source code

Spring is the basis for mastering java skills. Mastering spring technology is equivalent to winning half of java.

We use spring framework 5.3.10 to discuss the technical framework in annotation mode

Spring is actually like a factory. Every time the program starts to end, it is the process from the establishment of the factory to bankruptcy. This is a factory that produces beans. Here we understand beans as intelligent robots. The factory generally cooperates with various departments. The general procedure is that the purchasing department first purchases the raw materials, the processing department performs preliminary processing of the raw materials, and the production department is responsible for the final production of finished products.

Then the factory is established, the first thing not to do is to build the factory and create departmental facilities. Today we will look at this process from the perspective of source code.


The spring startup is the following line of code

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
复制代码

Take a closer look at the source code

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  this();
  register(componentClasses);
  refresh();
 }
复制代码

into this method:

public AnnotationConfigApplicationContext() {
  StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
  this.reader = new AnnotatedBeanDefinitionReader(this);
  createAnnotatedBeanDefReader.end();
  this.scanner = new ClassPathBeanDefinitionScanner(this);
 }
复制代码

The above is the entire source code of spring boot

Let's take a look at their corresponding roles:

AnnotationConfigApplicationContext is the context of spring boot in annotation mode, it is equivalent to that factory, and all departments belong to this factory.

this.scanner means scanning. This class is responsible for scanning according to the configured scanning path and acts as the purchasing department.

this.reader means reading. This class generates a BeanDefinition object based on the scanned class and reads the configuration information on the class, which acts as the primary processing department.

At this point we see the purchasing department and the processing department. Where is the production department?

In fact, to start a factory, not only these three departments are enough, but also some other small departments are required to be responsible for small functions, such as cleaning, logistics, fleet, sales, operations and so on.

We have to first take a look at the class diagram of AnnotationConfigApplicationContext

Let's analyze the spring mode first. Through this class diagram, I have to say that spring makes full use of the object-oriented inheritance feature, and uses the inheritance implementation of some abstract classes and interfaces properly. This is also the abstraction I used in the object-oriented chapter The reason why classes and interfaces are merged in inheritance characteristics, yes, object-oriented foundation is very important, and no matter how strong the framework is, it is also a full use of the foundation. At the same time, each interface separates the function, which is both isolation and single responsibility, spring fully It shows the charm of interface-oriented programming.

看整个类图其实就是上层接口不断向下层接口归并功能的过程,最终由实现类完成功能填充:结合源码我们看一下关系

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver
    
复制代码

EnvironmentCapable:提供获取运行时环境变量功能; MessageSource:提供国际化功能; ApplicationEventPublisher:提供事件机制功能; ResourcePatternResolver:提供加载资源功能; ListableBeanFactory和HierarchicalBeanFactory是BeanFacory的子类,BeanFacory在spring中成为bean工厂,但是在我们这个例子中我们称之为生产部门,这个接口有很多的子接口,孙子接口,这的ListableBeanFactory继承它,为它增加了bean实例批处理的功能,而HierarchicalBeanFactory继承它,为它增加了父容器的处理功能。

ApplicationContext接口继承了上面的所有接口,也就拥有了上面接口提供的所有功能;

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable 
复制代码

Lifecycle:提供了容器生命周期的相关功能 Closeable:提供了对资源关闭的功能

ConfigurableApplicationContext接口继承了上面的所有接口,也就拥有了ApplicationContext,Lifecycle,Closeable 接口提供的所有功能;

public abstract class AbstractApplicationContext extends DefaultResourceLoader
  implements ConfigurableApplicationContext
复制代码

DefaultResourceLoader类实现了ResourceLoader接口把接口功能填充完整,从而提供了资源加载的功能,和上面的ResourcePatternResolver接口不同,ResourcePatternResolver继承了ResourceLoader接口,只是对ResourceLoader接口的功能增加。

AbstractApplicationContext这个抽象类继承了DefaultResourceLoader,那么它就拥有了DefaultResourceLoader的功能,并且这些功能已经被实现,同时它又实现了ConfigurableApplicationContext,我们知道ConfigurableApplicationContext中融合了很多的接口功能,以为类实现实现接口就要实现接口中的所有方法,包括ResourcePatternResolver接口增强的的那一个方法。 AbstractApplicationContext是一个抽象类,它实现了所有接口的同时,它也有自己的抽象方法等待子类类实现。

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry
复制代码

BeanDefinitionRegistry:提供了BeanDefinition相关操作的功能

GenericApplicationContext类继承了AbstractApplicationContext抽象类,实现了BeanDefinitionRegistry接口,这个具体类此时已经拥有了上面所有功能的具体实现。

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry 
复制代码

AnnotationConfigRegistry:定义了扫描和注册的功能, AnnotationConfigApplicationContext最终继承了GenericApplicationContext类,并且实现了AnnotationConfigRegistry接口,从而一个完整的工厂形成了,已经完善了各种功能。

那么生产部门在哪里呢,我直接开门见山吧,

GenericApplicationContext类中有个DefaultListableBeanFactory类型的成员变量,这个类实际上也是BeanFactory家族的子子孙孙中的一个,那么这个属性是什么时候初始化的呢?我们可以看到在GenericApplicationContext类的构造方法中给这个属性赋了值,因为AnnotationConfigApplicationContext是GenericApplicationContext子类,所有AnnotationConfigApplicationContext实例化的时候会先一步调用父类的构造方法,从而初始化DefaultListableBeanFactory这个bean工厂。

首先这里采用组合方式,我们之前的文章说过能用组合就不用继承,这里比较有意思,beanFactory提供对bean操作的接口,由AnnotationConfigApplicationContext家族来实现,但是AnnotationConfigApplicationContext把实现又委托给beanFactory家族的子孙GenericApplicationContext来实现,这就是专人做专事,AnnotationConfigApplicationContext家族是统筹全局的,干活的还是得交给下面的部门。

实际上我们上面说的所有都是在讲this方法。

那么下面这两个方法是做什么呢? register(componentClasses); refresh();

实际上this方法完成后,这个工厂就已经创建完成。接下来就是到了真正干活的时候了,下面两个方法就开启了生产bean的整个过程。我们下回分解。

了解更多请关注微信公众号:码农本农

Guess you like

Origin juejin.im/post/7080355659274780708