提示: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
- 在spring的配置文件中,用bean标签来定义
- @Bean 在类上、方法上加注解来实现
- @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,也是非常核心的。

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

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

-
ConfigurableApplicationContext : 继承了ApplicationContext接口,增加了,添加时间监听器、添加BeanFactoryPostProcessor、设置Environment,获取ConfigurableListableBeanFactory等功能
-
AbstractApplicationContext : 实现了ConfigurableApplicationContext接口
-
GenericApplicationContext :继承了AbstractApplicationContext,实现了BeanDefinitionRegistry接口,拥有了所有ApplicationContext的功能,并且可以注册BeanDefinition,注意这个类有一个属性(DefaultListableBeanFactory
beanFactory) -
AnnotationConfigRegistry : 可以单独注册某个类为BeanDefinition(可以处理该类上的@Configuration注解,可以处理@Bean注解),同时可以扫描
-
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中管理
- 转换方式 (PropertyEditor)
package com.zheng.entity

最低0.47元/天 解锁文章
582

被折叠的 条评论
为什么被折叠?



