前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring底层架构源码解析(二)

Spring底层架构源码解析(二)

作者头像
ma布
发布2024-10-21 19:10:47
740
发布2024-10-21 19:10:47
举报
文章被收录于专栏:Java开发

有关该篇内容的前置知识可以参考我上篇文章:spring底层源码脉络解析

有关手写简单的实现spring的代码可以参考我的个人仓库:gitee仓库代码

BeanDefiniton

BeanDefiniton是spring源码中比较一个重要的接口,该接口描述了Bena的基本属性,该BeanDefiniton继承了AttributeAccessor, BeanMetadataElement接口,BeanDefiniton也有很多的方法可供实现,以下为其中方法的一部分截图:

其中BeanDefiniton有很多的属性可以值得我们去了解的

class,表示Bean类型 scope,表示Bean作用域,单例或原型等 lazyInit:表示Bean是否是懒加载 initMethodName:表示Bean初始化时要执行的方法 destroyMethodName:表示Bean销毁时要执行的方法

在spring中,我们创建一个Bean时有两类方式(声明式方式,编程类方式),而在声明式方式中又有以下几种方式:

1.使用xml方式:<bean/>

2.使用注解方式@Bean,@Component(@Service,@Controller)

在编程式方式中就可以使用到BeanDefinition

代码语言:javascript
复制
public class Test {

	public static void main(String[] args) {

		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        // 生成一个BeanDefinition对象,并设置beanClass为User.class,并注册到ApplicationContext中 
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
		beanDefinition.setBeanClass(User.class);
		applicationContext.registerBeanDefinition("User",beanDefinition);

		System.out.println(applicationContext.getBean("User"));
  }
}

我们说了BenaDefinition可以定义Bean的属性值

代码语言:javascript
复制
        //设置作用域
		beanDefinition.setScope("prototype");
		//设置懒加载
		beanDefinition.setLazyInit(true);
		//设置初始方法
		beanDefinition.setInitMethodName("Init");

不管是声明式还是编程式定义的Bean最终都会被spring解析为BeanDefiniton对象,然后被spring所管理

BeanDefinitionReader(读取器)

AnnotatedBeanDefinitionReader

可以直接把某个类转换为BeanDefinition,并且会解析该类上的注解,但是解析注解也是有范围的它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、 @Role、@Description

代码语言:javascript
复制
AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(AppConfig.class); 
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new 
AnnotatedBeanDefinitionReader(context); 
// 将User.class解析为BeanDefinition 
annotatedBeanDefinitionReader.register(User.class); 
System.out.println(context.getBean("user")); 

XmlBeanDefinitionReader

可以解析<bean/>标签

代码语言:javascript
复制
AnnotationConfigApplicationContext context = new 
AnnotationConfigApplicationContext(AppConfig.class); 
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context); 
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml"); 
System.out.println(context.getBean("user")); 

ClassPathBeanDefinitionScanner (扫描器)

ClassPathBeanDefinitionScanner为扫描器,与BeanDefinitionReader十分相似,它的作用是扫描某个包的路径,然后去解析该类上是否加了@Component注解,然后解析为BeanDefiniton对象

代码语言:javascript
复制
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); 
context.refresh(); 
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context); 
scanner.scan("com.lcyy"); 
System.out.println(context.getBean("userService")); 

BeanFactory

BeanFactory顾名思义为定义Bean的工厂,当我们使用ApplicationContext时,追踪源码可以发现ApplicationContext继承了ListableBeanFactory 和HierarchicalBeanFactory,ListableBeanFactory和HierarchicalBeanFactory都继承至 BeanFactory,所以我们可以认为ApplicationContext继承了BeanFactory。

ApplicationContext也是BeanFactory的一种,拥有BeanFactory支持的所有功 能,不过ApplicationContext比BeanFactory更加强大,ApplicationContext还基础了其他接口,也 就表示ApplicationContext还拥有其他功能,比如MessageSource表示国际化,ApplicationEventPublisher表示事件发布,EnvironmentCapable表示获取环境变量,等等。

在Spring的源码实现中,当我们new一个ApplicationContext时,其底层会new一个BeanFactory出 来,当使用ApplicationContext的某些方法时,比如getBean(),底层调用的是BeanFactory的 getBean()方法。

在spring的源码中,有一个叫做DefaultListableBeanFactory的实现类,DefaultListableBeanFactory有很多很实用的功能,并且DefaultListableBeanFactory继承了很多接口,在idea的继承图如下:

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的功能 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、 AutowireCapableBeanFactory、ConfigurableBeanFactory 14. AbstractAutowireCapableBeanFactory:继承了AbstractBeanFactory,实现了 AutowireCapableBeanFactory,拥有了自动装配的功能 15. DefaultListableBeanFactory:继承了AbstractAutowireCapableBeanFactory,实现了 ConfigurableListableBeanFactory接口和B

有关spring的源码部分解析下一篇文章会继续详细说明的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • BeanDefiniton
  • BeanDefinitionReader(读取器)
    • AnnotatedBeanDefinitionReader
      • XmlBeanDefinitionReader
      • ClassPathBeanDefinitionScanner (扫描器)
      • BeanFactory
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档