【Spring之底层核心架构概念解析】

文章目录

  • 一、BeanDefinition
  • 二、BeanDefinitionReader
    • 2.1、AnnotatedBeanDefinitionReader
    • 2.2、XmlBeanDefinitionReader
  • 五、ClassPathBeanDefinitionScanner
  • 六、BeanFactory
  • 七、ApplicationContext
    • 7.1、AnnotationConfigApplicationContext
    • 7.2、ClassPathXmlApplicationContext
  • 八、类型转换
    • 8.1、PropertyEditor
    • 8.2、ConversionService
    • 8.3、TypeConverter
  • 九、FactoryBean
  • 十、ExcludeFilter和IncludeFilter
  • 十一、MetadataReader、ClassMetadata、AnnotationMetadata

前置准备测试对象User:


public class User {public User(int flag, String uuid){System.out.println(flag+"----------"+uuid);}public User(){System.out.println("User 无参构造");}}

一、BeanDefinition

BeanDefinition表示Bean的定义,其可记录Bean的特征,例如:

  1. Bean的类型:beanClass属性
  2. Bean的作用域:Scope属性
  3. Bean是否为懒加载:lazyinit属性

在Spring中,定义一个bean的方式主要有:XML文件中使用bean标签来定义其bean属性,除此外,可以使用@Bean注解以及@Component等注解来定义注解,当然,也可以使用编程式来定义Bean,如下代码:

//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);//定义一个BeanDefinition对象AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();//向BeanDefinition对象中添加对象信息beanDefinition.setBeanClass(User.class);beanDefinition.setScope("prototype");//将BeanDefinition对象加入到Spring容器中context.registerBeanDefinition("user",beanDefinition);System.out.println("Spring BeanDefinition 创建的user对象为:"+context.getBean("user"));UserService userService = (UserService) context.getBean("userService");userService.test();}
}

在这里插入图片描述

二、BeanDefinitionReader

其表示BeanDefinition读取器,主要的读取方式有以下两种

2.1、AnnotatedBeanDefinitionReader

这个组件可以将某各类直接转换为BeanDefinition,并且会解析该类上的注解,测试代码如下:

//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);//声明一个BeanDefinition读取器,并在这个读取器中传入Spring容器AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);annotatedBeanDefinitionReader.register(User.class);System.out.println("BeanDefinition读取器AnnotatedBeanDefinitionReader创建bean为:"+context.getBean("user"));UserService userService = (UserService) context.getBean("userService");userService.test();}
}

在这里插入图片描述

2.2、XmlBeanDefinitionReader

该接口主要是通过解析XML文件中的Bean标签进行BeanDefinition转换,代码如下:

XML配置文件信息:
在这里插入图片描述

//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);//声明一个BeanDefinition读取器,并在这个读取器中传入Spring容器XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");System.out.println("扫描到bean标签数量:"+i);System.out.println("BeanDefinition读取器XmlBeanDefinitionReader创建bean为:"+context.getBean("user"));UserService userService = (UserService) context.getBean("userService");userService.test();}
}

在这里插入图片描述

五、ClassPathBeanDefinitionScanner

其为BeanDefinition资源扫描器,作用和BeanDefinitionReader类似,只是读取的方式是以指定路径的方式扫描类资源,对扫描到的类进行解析,是否包含其相关注解信息,例:如果类中包含@Component注解,就会将该类作为BeanDefinition对象放入到Spring容器中,代码如下:

@Component
public class UserService {public void test(){System.out.println("test--->Spring创建对象");}
}
//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.refresh();//声明一个BeanDefinition读取器,并在这个读取器中传入Spring容器ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);int scan = scanner.scan("com.practice.service");System.out.println("指定路径下,扫描到的bean资源数量:"+scan);System.out.println("ClassPathBeanDefinitionScanner扫描器创建bean为:"+context.getBean("userService"));}
}

在这里插入图片描述

六、BeanFactory

BeanFactory会负责创建Bean,并且提供获取Bean的API

七、ApplicationContext

ApplicationContext是BeanFactory的一种,其在Spring的源码中的定义为:
在这里插入图片描述

图中的ListableBeanFactory和HierarchicalBeanFactory都继承至BeanFactory,所以ApplicationContext也是具备BeanFactory具备的特性和功能,但是,ApplicationContext还具备额外的功能,例如,支持国际化、支持获取环境信息、支持事件发布和相关资源加载,其有两个实现类,如下介绍

7.1、AnnotationConfigApplicationContext

其源代码如下:
在这里插入图片描述

AnnotationConfigApplicationContext继承了GenericApplicationContext,实现了AnnotationConfigRegistry接口,拥有了其父类以及父接口以及父接口继承甚至更向上的接口所有的功能

7.2、ClassPathXmlApplicationContext

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

八、类型转换

在Spring中,有可能会存在一些类型转换的问题,其Spring中提供了一些技术来方便做类型转换操作,在Spring源码中,与存在许多类型转换的操作,类型转化主要有以下接口

8.1、PropertyEditor

这是JDK自带的类型转换工具类,具体使用如下:

public class StringToUserPropertyEditor extends PropertyEditorSupport implements PropertyEditor {@Overridepublic void setAsText(String text) throws IllegalArgumentException {User user = new User();user.setName(text);this.setValue(user);}
}
//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {StringToUserPropertyEditor propertyEditor = new StringToUserPropertyEditor();propertyEditor.setAsText("1");User value = (User) propertyEditor.getValue();System.out.println(value);}
}

在这里插入图片描述

8.2、ConversionService

Spring中提供的类型转化服务,它比PropertyEditor更强大,其代码如下:

public class StringToUserConverter implements ConditionalGenericConverter {@Overridepublic boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {return sourceType.getType().equals(String.class) &&targetType.getType().equals(User.class);}@Overridepublic Set<ConvertiblePair> getConvertibleTypes() {return Collections.singleton(new ConvertiblePair(String.class, User.class));}@Overridepublic Object convert(Object source, TypeDescriptor sourceType, TypeDescriptortargetType) {User user = new User();user.setName((String)source);return user;}
}
//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {DefaultConversionService conversionService = new DefaultConversionService();conversionService.addConverter(new StringToUserConverter());User value = conversionService.convert("1", User.class);System.out.println(value);}
}

在这里插入图片描述

8.3、TypeConverter

整合了PropertyEditor和ConversionService的功能,是Spring内部用的,如下:

//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) {SimpleTypeConverter typeConverter = new SimpleTypeConverter();typeConverter.registerCustomEditor(User.class, new StringToUserPropertyEditor());User value = typeConverter.convertIfNecessary("1", User.class);System.out.println(value);}
}

在这里插入图片描述

九、FactoryBean

我们想一个Bean完完全全由我们来创造,可以通过FactoryBean来完成,如下:

public class factoryBeanTest implements FactoryBean {@Overridepublic Object getObject() throws Exception {UserService userService = new UserService();return userService;}@Overridepublic Class<?> getObjectType() {return UserService.class;}}

通过上面这段代码,我们自己创造了一个UserService对象,并且它将成为Bean。但是通过这种方式创造出来的UserService的Bean,只会经过初始化后,其他Spring的生命周期步骤是不会经过的,比如依赖注入

十、ExcludeFilter和IncludeFilter

这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表示排除过滤器,IncludeFilter表示包含过滤器,如下:
在这里插入图片描述

在这里插入图片描述
FilterType分为:
1. ANNOTATION:表示是否包含某个注解
2. ASSIGNABLE_TYPE:表示是否是某个类
3. ASPECTJ:表示否是符合某个Aspectj表达式
4. REGEX:表示是否符合某个正则表达式
5. CUSTOM:自定义

十一、MetadataReader、ClassMetadata、AnnotationMetadata

在Spring中需要去解析类的信息,比如类名、类中的方法、类上的注解,这些都可以称之为类的元数据,所以Spring中对类的元数据做了抽象,并提供了一些工具类
MetadataReader表示类的元数据读取器,默认实现类为SimpleMetadataReader。代码如下示例:

package com.practice.service;import org.springframework.stereotype.Component;@Component
public class UserService {public void test(){System.out.println("test--->Spring创建对象");}
}
//Spring核心概念测试类
public class TestSpringDemo {public static void main(String[] args) throws IOException {SimpleMetadataReaderFactory simpleMetadataReaderFactory = newSimpleMetadataReaderFactory();// 构造一个MetadataReaderMetadataReader metadataReader =simpleMetadataReaderFactory.getMetadataReader("com.practice.service.UserService");// 得到一个ClassMetadata,并获取了类名ClassMetadata classMetadata = metadataReader.getClassMetadata();System.out.println(classMetadata.getClassName());// 获取一个AnnotationMetadata,并获取类上的注解信息AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();for (String annotationType : annotationMetadata.getAnnotationTypes()) {System.out.println(annotationType);}}
}

在这里插入图片描述
注:SimpleMetadataReader去解析类时,使用的ASM技术。因为Spring启动的时候需要去扫描,如果指定的包路径比较宽泛,那么扫描的类是非常多的,那如果在Spring启动时就把这些类全部加载进JVM了,这样不太好,所以使用了ASM技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/187810.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Zeitgeist ZTG Token以及其预测市场加入Moonbeam生态

波卡上的首选多链开发平台Moonbeam宣布与Zeitgeist达成XCM集成&#xff0c;将ZTG Token引入Moonbeam。此集成将使波卡内的Moonbeam和Zeitgeist网络之间的流动性得以流动&#xff0c;并通过Moonbeam的互连合约实现远程链集成。 Zeitgeist是一个基于波卡的Substrate区块链框架构…

数据结构:AVL树的旋转(高度平衡树)

1、AVL树简介 AVL树是最先发明的自平衡二叉查找树。在AVL树中任何节点的两个子树的高度最大差别为1&#xff0c;所以它也被称为高度平衡树。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。AVL树得名于它的发明者G. M. Adelson-Velsky和E. M. Landis&#xff0c;他们…

Vuex:模块化Module :VCA模式

VCA中不支持辅助函数&#xff0c;因为辅助函数中是用this.$store&#xff0c;而VCA中没有绑定this的 由于使用单一状态树&#xff0c;应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时&#xff0c;store 对象就有可能变得相当臃肿。 这句话的意思是&#xff0c;…

初识Linux:目录路径

目录 提示&#xff1a;以下指令均在Xshell 7 中进行 一、基本指令&#xff1a; 二、文件 文件内容文件属性 三、ls 指令拓展 1、 ls -l &#xff1a; 2、ls -la&#xff1a; 3、ls [目录名] &#xff1a; 4、ls -ld [目录名]&#xff1a; 四、Linux中的文件和…

SpringBoot 使用EasyExcel 导出Excel报表(单元格合并)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、导入依赖二、代码1. 导出简单的Excel2. 代码控制导出报表的格式 总结 前言 SpringBoot 使用Alibaba提供的EasyExcel导出Excel报表。 本文中涉及的业务逻辑…

asp.net校园招聘管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 校园招聘管理系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语言开发 应用技术&#xff1a;asp.net c#s…

IP行业API助力于网络分析和数据挖掘

引言 在当今数字化时代&#xff0c;数据成为了企业、科研机构和政府决策者的重要资源&#xff0c;而IP行业API则成为了数据分析及挖掘的工具之一。IP行业API是一种能够查询IP地址所属的行业分类信息的应用程序接口&#xff0c;它能够提供在网络分析、用户行为分析及大数据挖掘…

LeetCode 面试题 16.20. T9键盘

文章目录 一、题目二、C# 题解 一、题目 在老式手机上&#xff0c;用户通过数字键盘输入&#xff0c;手机将提供与这些数字相匹配的单词列表。每个数字映射到0至4个字母。给定一个数字序列&#xff0c;实现一个算法来返回匹配单词的列表。你会得到一张含有有效单词的列表。映射…

农业大棚智能化改造升级与远程视频监管方案,助力智慧农业建设发展

一、需求分析 随着现代化技术的发展&#xff0c;农业大棚的智慧化也成为当前备受关注的智慧农业发展手段。利用先进的信息化手段来对农业大棚进行管理&#xff0c;采集和掌握作物的生长状况、作业监督、生态环境等信息数据&#xff0c;实现精准操作、精细管理&#xff0c;远程…

美格智能5G RedCap模组顺利完成中国联通5G物联网OPENLAB开放实验室认证

近日&#xff0c;美格智能5G RedCap模组SRM813Q顺利通过中国联通5G物联网OPENLAB开放实验室端到端的测试验收&#xff0c;并获得OPENLAB实验室的认证证书。这标志着该模组产品各项性能均已符合RedCap商用标准&#xff0c;为5G RedCap规模商用奠定了坚实基础。 中国联通5G物联网…

Kubernetes平台部署Grafana Loki Promtail系统

部署结构图&#xff1a; Loki 是主服务&#xff0c;负责存储日志和处理查询promtail 是代理&#xff0c;负责收集日志并将其发送给 lokiGrafana 用于 UI 展示 只要在应用程序服务器上安装promtail来收集日志然后发送给Loki存储&#xff0c;就可以在Grafana UI界面通过添加Lok…

Python基础教程:类--继承和方法的重写

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 什么是继承 继承就是让类与类之间产生父子关系&#xff0c;子类可以拥有父类的静态属性和方法 继承就是可以获取到另一个类中的静态属性和普通方法&#xff08;并非所有成员&#xff09; 在python中&#xff0c;新建的类可…

导轨式安装压力应变桥信号处理差分信号输入转换变送器0-10mV/0-20mV/0-±10mV/0-±20mV转0-5V/0-10V/4-20mA

主要特性 DIN11 IPO 压力应变桥信号处理系列隔离放大器是一种将差分输入信号隔离放大、转换成按比例输出的直流信号导轨安装变送模块。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等行业。此系列模块内部嵌入了一个高效微功率的电源&#xff0c;向输入端和输…

Visual Studio2022安装教程【图文详解】(大一小白)编译软件

工欲善其事&#xff0c;必先利其器。想要学好编程&#xff0c;首先要把手中的工具利用好&#xff0c;今天小编教一下大家如何下载安装并使用史上最强大的编译器--Visual Studio&#x1f357; 一.Visual Studio下载及安装 https://visualstudio.microsoft.com/ 打开文件 点击.ex…

基于ubuntu 22, jdk 8x64搭建图数据库环境 hugegraph--google镜像chatgpt

基于ubuntu 22, jdk 8x64搭建图数据库环境 hugegraph download 环境 uname -a #Linux whiltez 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64 x86_64 x86_64 GNU/Linuxwhich javac #/adoptopen-jdk8u332-b09/bin/javac which java #/adoptopen-jdk8u33…

对于线程的收尾

一)对于synchronized的锁策略: synchronzed是一个自适应的锁&#xff0c;应该根据具体情况来决定选取那种锁策略&#xff1b; 1)synchronized既是一个乐观锁又是一个悲观锁&#xff0c;一开始是一个乐观锁&#xff0c;但是如果发现锁冲突的概率比较高&#xff0c;就会自动转化成…

主题模型LDA教程:一致性得分coherence score方法对比(umass、c_v、uci)

文章目录 主题建模潜在迪利克雷分配&#xff08;LDA&#xff09;一致性得分 coherence score1. CV 一致性得分2. UMass 一致性得分3. UCI 一致性得分4. Word2vec 一致性得分5. 选择最佳一致性得分 主题建模 主题建模是一种机器学习和自然语言处理技术&#xff0c;用于确定文档…

Linux驱动开发——USB设备驱动

目录 一、 USB 协议简介 二、 Linux USB 驱动 三、 USB 设备驱动实例 一、 USB 协议简介 USB(Universal Serial Bus&#xff0c;通用串行总线)正如它的名字一样&#xff0c;是用来连接PC外设的一种通用串行总线&#xff0c;即插即用和易扩展是它最大的特点。所谓即插即用&am…

Edge浏览器新建标签页如何更改为指定网址

Edge浏览器新建标签页如何更改为指定网址&#xff1f; 启动时新建标签页 不是说启动时&#xff0c;而是加号新建标签页时候 启动时 新建标签页 New Tab Changer 可以了 如果没有需要应用商店下载 参考文章

Clickhouse 学习笔记(6)—— ClickHouse 分片集群

前置知识&#xff1a; Clickhouse学习笔记&#xff08;5&#xff09;—— ClickHouse 副本-CSDN博客 与副本对比&#xff1a; 副本虽然能够提高数据的可用性&#xff0c;降低丢失风险&#xff0c;但是每台服务器实际上必须容纳全量数据&#xff0c;对数据的横向扩容没有解决 …