Spring源码-核心概念介绍

提示:Spring整体源码架构前置核心概念解析。BeanDefinition、BeanPostProcessor、aop的底层原理、spring源码核心、BeanPostProcessor,最简单学源码。BeanDefinition、BeanDefinitionReader、ClassPathBeanDefinitionScanner、BeanFactory、ApplicationContext、MessageSource、事件发布、类型转换、排序、MetadataReader(元数据)、BeanPostProcessor、BeanFactoryPostProcessor、ExcludeFilter和IncludeFilter。、FactoryBean、BeanPostProcessor

前言


直接看spring源码的时候,会感觉很吃力。我们这里主要介绍一些,常用的spring中的组件以及核心概念。目的是通过看这个类的名字,就知道它大概是用来干嘛的,从而方便我们更轻松的阅读源码。本人水平有限,如有误导,欢迎斧正,一起学习,共同进步!


一、总体概览

这里主要是一些比较核心的功能点。

1、BeanDefinition

2、BeanDefinitionReader

3、ClassPathBeanDefinitionScanner

4、BeanFactory

5、ApplicationContext

6、MessageSource

7、事件发布

8、类型转换

9、排序

10、MetadataReader(元数据)

11、BeanPostProcessor

12、BeanFactoryPostProcessor

13、ExcludeFilter和IncludeFilter。

14、FactoryBean

15、BeanPostProcessor

二、详细介绍

1、BeanDefinition

beanDefinition 是一个接口,表示bean的定义,是bean的一些公共的属性。

  • class : bean的类型
  • scope : bean的作用域,单例或者多例
  • lazyInit : bean是否是懒加载。
  • initMethodName : bean初始化时要执行的方法
  • destoryMethodName : bean销毁时要执行的方法

在spring中,我们通常会通过一下几种方式来定义bean

  1. 在spring的配置文件中,用bean标签来定义
  2. @Bean 在类上、方法上加注解来实现
  3. @Component ,直接在类上加@Component来定义

这些我们称为是声明式定义bean,我们还有编程式定义bean(其实就是我们自己new 一个对象,然后放到spring容器中)。
编程式定义bean:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);

// 类似于new对象,这里是用builder去创建的对象
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
// 给创建的对象set值
beanDefinition.setBeanClass(User.class);
// 将new出来的对象,交给spring管理,放到spring的容器中去
context.registerBeanDefinition("user", beanDefinition);

beanDefinition接口中有一个很强大的实现类,GenericBeanDefinition,这里面有beanDefinition的全部实现。这个GenericBeanDefinition类下又有俩类:ScannedGenericBeanDefinition、AnnotatedGenericBeanDefinition。其中如果是spring中的扫描,被扫描出来的bean,创建的就是ScannedGenericBeanDefinition类型;如果是通过各种各样的beanDefinitionReader去生成的bean,就是AnnotatedGenericBeanDefinition类型。简单的说,spring创建的beanDefinition都是beanDefinition类型,但是通过创建的方式不同,底层是不同的beanDefinition实现。

当然,spring中也有其他的比较重要的实现,比如说 RootBeanDefinition(现在还比较常用,是跟合并beanDefinition有关系的),ChildBeanDefinition(spring2.5以后不怎么常用了)。

2、BeanDefinitionReader

beanDefinition读取器(beanDefinitionReader)可以将某个类转换为beanDefinition,是spring中常用的,相当于spring中的基础设置。

  • AnnotatedBeanDefinitoinReader : 可以吧某个类转换为beanDefinition,并且会解析该类的注解
  • XmlBeanDefinitionReader : 可以解析 标签,转换为beanDefinition

3、ClassPathBeanDefinitionScanner

classPathBeanDefinitoinScanner是扫描器,有点类似于beanDefinitionReader,他可以进行扫描,扫描某个包路径,对扫描到的类进行解析,比如,如果扫描到com.zheng文件夹下,看到user1、user2、user3,3个类,就会把这三个类中带有@Commont注解的类,解析为一个个的beanDefinition。

4、BeanFactory

beanFactory表示bean工厂。会提供一些getBean、crateBean之类的方法。它有一个非常重要的实现类,叫:DefaultListableBeanFactory,也是非常核心的。

在这里插入图片描述
他继承了很多接口,表示它有很多功能:

  1. AliasRegistry : 支持别名功能,一个名字可以对应多个别名
  2. BeanDefinitionRegistry : 可以注册、保持、移除某个beanDefinition
  3. beanFactory : Bean工厂,可以根据某个bean的名字、别名、类型去获取某个bean对象
  4. SingletonBeanRegistry : 可以注册、获取某个单例bean
  5. SimpleAliasRegistry : 他是一个类,实现了AliasRegistry接口中定义的所有功能,支持别名功能
  6. ListableBeanFactory : 在BeanFactory的基础上,增加了其他功能,可以获取所有的beanDefinition的beanNames,可以根据某个类型获取对应的beanNames,可以根据某个类型获取{类型:对应的bean}的映射关系
  7. HierarchicalBeanFactory : 在BeanFactory的基础上,添加了获取父BeanFactory的功能。(如果子类的beanFactory中没有的话,可以去父的beanFactory找这个对象)
  8. DefaultSingletonBeanRegistry : 它是一个类,实现了SingletonBeanRegistry接口,拥有了直接注册、获取某个单例Bean的功能。
  9. ConfigurableBeanFactory : 在HierarchicalBeanFactory和SingletonBeanRegistry的基础上,添加了设置父BeanFactory、类加载器(表示和可以指定某个类加载器进行类的加载)、设置Spring
    EL表达式解析器(标示该BeanFactory可以解析EL表达式)、设置类型转化服务(表示该beanFactory可以进行类型转换)、可以添加BeanPostProcessor(表示该beanFactory支持bean的后置处理器),可以合并BeanDefinition,可以销毁某个bean等等功能
  10. FactoryBeanRegistrySupport : 支持了FactoryBean的功能
  11. AutowireCapableBeanFactory : 是直接继承了BeanFactory,在BeanFactory的基础上,支持在创建Bean的过程中能对Bean进行自动装配
  12. AbstractBeanFactory : 实现了ConfigurableBeanFactory接口,继承了FactoryBeanRegistrySupport,这个BeanFactory的功能已经已经很全面了,到那时不能自动装配和获取beanNames
  13. ConfigurableListableBeanFactory : 继承了ListableBeanFactory、AutowiredCapableBeanFactory、ConfigurableBeanFactory
  14. AbstractAutowireCapableBeanFactory : 继承了AbstractBeanFactory,实现了AutowireCapableBeanFactory,拥有了自动装配的功能
  15. DefaultListableBeanFactory : 继承了AbstractAutowireCapableBeanFactory,实现了ConfigurableListableBeanFactory接口和BeanDefinitionRegistry接口,所以DefaultListableBeanFactory的功能很强大

5、ApplicationContext

applicationContext集成了beanFactory,所以你可以简单的认为,他就是个beanFactory,毕竟它继承了beanFactory,有他的全部功能。

在这里插入图片描述

  • ListableBeanFactory : 是继承的BeanFactory,拥有父类的BeanFactory的功能(创建bean、getBean啊之类的)
  • HierarchicalBeanFactory :是继承的BeanFactory,还拥有获取beanNames的功能
  • EnvironmentCapable :可以获取运行时环境的功能(没有设置运行时环境的功能)
  • MessageSource :拥有直接进行国际化的功能
  • ApplicationEventPublisher :拥有广播事件的功能(没有添加事件发生器的功能) 事件发布器。同样也说明了,它还具有事件发布的相关功能。
  • ResourcePatternResolver : 资源加载器,可以一次性获取多个资源(文件资源等等)。直接去获取某些资源的功能。

ApplicationContext有两个比较重要的实现类:

  1. AnnotationConfigApplicationContext
  2. ClassPathXmlApplicationContext

在这里插入图片描述

  1. ConfigurableApplicationContext : 继承了ApplicationContext接口,增加了,添加时间监听器、添加BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能

  2. AbstractApplicationContext : 实现了ConfigurableApplicationContext接口

  3. GenericApplicationContext :继承了AbstractApplicationContext,实现了BeanDefinitionRegistry接口,拥有了所有ApplicationContext的功能,并且可以注册BeanDefinition,注意这个类有一个属性(DefaultListableBeanFactory
    beanFactory)

  4. AnnotationConfigRegistry : 可以单独注册某个类为BeanDefinition(可以处理该类上的@Configuration注解,可以处理@Bean注解),同时可以扫描

  5. AnnotationConfigApplicationContext : 继承了GenericApplicationContext,实现了AnnotationConfigRegistry接口,拥有了以上的所有的功能

在这里插入图片描述
它也是继承了AbstractApplicationContext,但是相对于AnnotationConfigApplicationContext而言,功能没有AnnotationConfigApplicationContext强大,比如不能注册beanDefinition。

怎么获取一个ApplicationConext

方式1:(亲测可用) 实现了ApplicationContextAware

package com.zheng.entity;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author: ztl
 * @date: 2024/05/14 22:29
 * @desc:
 */
@Component
public class TestApplicationContext implements ApplicationContextAware {
   
   
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
   
   
        this.applicationContext = applicationContext;
    }

    public void test(){
   
   
        applicationContext.publishEvent("123");
        System.out.println("TestApplicationContext publishEvent start ");
    }
}

方式2:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   
   

    private Integer id;

    private String name;

    public static void main(String[] args) {
   
   
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//        context.publishEvent("222");

        TestApplicationContext testApplicationContext = (TestApplicationContext) context.getBean("TestApplicationContext");
        testApplicationContext.test();;
    }
}

6、MessageSource

国际化,其实就是说能选择语言。有点类似于 applicatoin-pro.properties 中的pro一样。定义一个MessageSource可以在任意想要进行国际化的地方使用这个MessageSource

7、事件发布

定义一个时间监听器(有点类似于mq的消费者,不过不用指定名字、队列之类的)

@Bean
public ApplicationListener applicationListener() {
   
   
 return new ApplicationListener() {
   
   
  @Override
  public void onApplicationEvent(ApplicationEvent event) {
   
   
   System.out.println("接收到了一个事件");
  }
 };
}

在去发布事件:ApplicationContext context; context.publishEvent(“kkk”);
在这里插入图片描述

8、类型转换

在spring源码中,有可能需要把String转成其他类型,所以在spring源码中提供了一些技术来更方便的做对象类型的转换,关于类型转换的应用场景,后续看源码的过程中会遇到很多。

8.1、PropertyEditor (jdk提供的)

这其实是JDK提供的类型转换工具类。
如图所示,比如我想把@Value里面的值,赋值给user中的某个属性,怎么实现。
在这里插入图片描述
步骤很简单,1、定义一个转换的方式,2、将这个转换方式,放到spring中管理

  1. 转换方式 (PropertyEditor)
package com.zheng.entity
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值