• Spring 源码解读(1) - Spring上下文构造方法的初始化


    Spring上下文构造方法的初始化

    JavaConfig 方式加载 Spring 容器

    JavaConfig 方式加载 Spring 容器的是 new 一个 AnnotationConfigApplicationContext()
    
    • 1
    • 代码如下:
    @Configuration
    @ComponentScan
    public class SpringConfig {
    
        @Bean
        public Bean2 getUserServie(){
            return new Bean2();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
        public static void main(String[] args) {
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
            UserService userService = applicationContext.getBean(UserService.class);
            userService.doSomething1();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    源码解读

    在这个构造方法中,分为三步:

    public AnnotationConfigApplicationContext(Class... componentClasses) {
        // 1:无参构造方法的初始化
        this();
        // 2:将配置类注册到 beanDefinition中去
        this.register(componentClasses);
        // 3:调用refresh() 开始IOC 流程 
        this.refresh();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    无参构造方法初始化

    分为两步:

    • 调用父类的构造方法
    • 本类的构造方法

    调用父类的构造方法

    在父类的构造方法中,初始化BeanFactory 接口的实现类:DefaultListAbleBeanFactory。这个类是用来使用工厂模式+反射生成bean的

    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
    
    • 1
    • 2
    • 3

    调用本类的构造方法

    public AnnotationConfigApplicationContext() {
        this.reader = new AnnotatedBeanDefinitionReader(this);
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    
    • 1
    • 2
    • 3
    • 4
    • new 一个 BeanDefinationReader,它是用来读取配置类的,并封装成一系列的BeanDefinition ,后续spring 基于这个bean定义去生产bean

    • new 一个 BeanDefinitionScanner,它是用来扫描在外部添加需要被扫描的类,并不会扫描配置文件中的通过componmentScan 配置的包路径。

    创建 BeanDefinationReader

    这一步会将一些后置处理器注册到 BeanDefinition 中,也就是将几个后置处理器接口封装成一个个的 bean定义。这些后置处理器有实现 bean工厂的后置处理器,也有实现了bean的后置处理器。比如:ConfigurationClassPostProcessor 实现了 bean 工厂后置处理器,用于解析加了 @Configuration 注解、 @ComponmentScan 、@ComponmentScans、@Import 等这些注解。还有一些解析 @Autowired注解的、解析 @Resource、@Ejb注解的,还有一些是监听器的处理器。
    这样做的目的是:在生产 bean 的时候要用到这些后置处理器。
    在这里插入图片描述

    在这里插入图片描述

    加载过后的beanDefinition 中的样子
    在这里插入图片描述

    创建 BeanDefinitionScanner

    • scanner 是为了解析手动加了扫描路径的那些类,注册到 bean定义中, 它不会去扫描配置文件中写的@ComponmentScan 的路径,那些路径是 BeanDefinationReader 中的后置处理器去扫描的。
    public static void main(String[] args) {
    		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(IOCConfig.class);
    		// 手动需要设置一个需要扫描的包
    		context.scan("com.ioc");
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5

    将配置类注册到 beanDefinition

    在这里插入图片描述

    • 这一步的目的是将 配置类存入 beanDefinition 中,因为并没有解析它
      至此,配置文件的注册都完成了,主要就是将一些后置处理器、配置文件信息封装成 beanDefinition ,以及创建bean工厂。接下来就是 IOC 流程。
  • 相关阅读:
    autojs操作
    2023八股每日一题(九月份)
    SpringMVC使用(二)
    计算机操作系统-第十一天
    广和通5G模组FM650助力阿里云打造无影魔方Pro
    centos7下docker的安装
    操作系统之微内核架构
    C++基础——new和delete动态开辟
    Linux终端操作-Xshell和Xftp(家庭版)
    如何在Git中修改远程仓库地址
  • 原文地址:https://blog.csdn.net/qq_30450563/article/details/126126493