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

目录

ApplicationContext

AnnotationConfigApplicationContext

ClassPathXmlApplicationContext 

类型转换 

PropertyEditor

ConversionService

BeanPostProcessor

FactoryBean 

MetadataReader、ClassMetadata、 AnnotationMetadata

ExcludeFilter,IncludeFilter


有关spring的前置知识,可以观看我的上一篇文章spring底层架构源码解析(二)

ApplicationContext

接上一篇文章,再将到BeanFactory后不得不提到ApplicationContext了,ApplicationContext其实是继承了BeanFactory的,但是ApplicationContext提供了比BeanFactory更多的功能,其中ApplicationContext两个比较重要的实现类:

1. AnnotationConfigApplicationContext

2. ClassPathXmlApplicationContext

AnnotationConfigApplicationContext

在idea的继承图如下,可以发现AnnotationConfigApplicationContext实现了很多的接口

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接口,拥有了以上所有的功能  

ClassPathXmlApplicationContext 

同样,在idea的继承图如下,可以发现ClassPathXmlApplicationContext实现了很多的接口

类型转换 

在spring的源码中有许多类型转换的工具类,例如:PropertyEditor,ConversionService,TypeConverter等,他们可以将我们写的String转换为spring需要加载的类对象

PropertyEditor

public class StringToUserPropertyEditor extends PropertyEditorSupport implements 
PropertyEditor { @Override public void setAsText(String text) throws IllegalArgumentException { User user = new User(); user.setName(text); this.setValue(user); } 
} 

如何向Spring中注册PropertyEditor:

@Bean 
public CustomEditorConfigurer customEditorConfigurer() { CustomEditorConfigurer customEditorConfigurer = new CustomEditorConfigurer(); Map<Class<?>, Class<? extends PropertyEditor>> propertyEditorMap = new HashMap<>(); // 表示StringToUserPropertyEditor可以将String转化成User类型,在Spring源码中,如果发现当前
对象是String,而需要的类型是User,就会使用该PropertyEditor来做类型转化 propertyEditorMap.put(User.class, StringToUserPropertyEditor.class); customEditorConfigurer.setCustomEditors(propertyEditorMap); return customEditorConfigurer; 
} 

ConversionService

ConversionService是比PropertyEditor更为强大的类型转换类

public class StringToUserConverter implements ConditionalGenericConverter { @Override public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) { return sourceType.getType().equals(String.class) && 
targetType.getType().equals(User.class); } @Override public Set<ConvertiblePair> getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(String.class, User.class)); } @Override public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor 
targetType) { User user = new User(); user.setName((String)source); return user; } 
} 

如何向Spring中注册ConversionService:

@Bean 
public ConversionServiceFactoryBean conversionService() { ConversionServiceFactoryBean conversionServiceFactoryBean = new 
ConversionServiceFactoryBean(); conversionServiceFactoryBean.setConverters(Collections.singleton(new 
StringToUserConverter())); return conversionServiceFactoryBean; 
} 

BeanPostProcessor

BeanPostProcess表示Bena的后置处理器,我们可以定义一个或多个BeanPostProcessor,比如通 过以下代码定义一个BeanPostProcessor:

@Component 
public class LcyyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws 
BeansException { if ("userService".equals(beanName)) { System.out.println("Bean的初始化前"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws 
BeansException { if ("userService".equals(beanName)) { System.out.println("Bean的初始化后"); } return bean; } 
} 

一个BeanPostProcessor可以在任意一个Bean的初始化之前以及初始化之后去额外的做一些用户自 定义的逻辑,当然,我们可以通过判断beanName来进行针对性处理(针对某个Bean,或某部分 Bean)。 因此可以通过定义BeanPostProcessor来干涉Spring创建Bean的过程。

FactoryBean 

FactoryBean 其实是一个比较特殊的Bean,可以通过BeanPostPorcessor来干涉Spring创建Bean的过程,但是如果我们想一个 Bean完完全全由我们来创造,也是可以的,比如通FactoryBean

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

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

MetadataReader、ClassMetadata、 AnnotationMetadata

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

public class Test { public static void main(String[] args) throws IOException { SimpleMetadataReaderFactory simpleMetadataReaderFactory = new 
SimpleMetadataReaderFactory(); // 构造一个MetadataReader MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.lcyy.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); } } 
} 

ExcludeFilter,IncludeFilter

这两个Filter是Spring扫描过程中用来过滤的。ExcludeFilter表示排除过滤器,IncludeFilter表示包 含过滤器。 比如以下配置,表示扫描com.lcyy这个包下面的所有类,但是排除UserService类,也就是就算它上面有@Component注解也不会成为Bean。

@ComponentScan(value = "com.lcyy", excludeFilters = {@ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE,  classes = UserService.class)}.) 
public class AppConfig { 
}

再比如以下配置,就算UserService类上没有@Component注解,它也会被扫描成为一个Bean。

@ComponentScan(value = "com.lcyy", includeFilters = {@ComponentScan.Filter( type = FilterType.ASSIGNABLE_TYPE,  classes = UserService.class)}) 
public class AppConfig { 
}

FilterType分为:

1. ANNOTATION:表示是否包含某个注解

2. ASSIGNABLE_TYPE:表示是否是某个类

3. ASPECTJ:表示否是符合某个Aspectj表达式

4. REGEX:表示是否符合某个正则表达式

5. CUSTOM:自定义

在Spring的扫描逻辑中,默认会添加一个AnnotationTypeFilter给includeFilters,表示默认情况下 Spring扫描过程中会认为类上有@Component注解的就是Bean。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【2025】基于微信小程序的人工智能课程学习平台的设计与实现(源码+文档+解答)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

如何使用ssm实现企业文档管理系统+vue

TOC ssm648企业文档管理系统vue 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进行科学化&#xff0c;规范化管理。…

htop(1) command

文章目录 1.简介2.格式3.选项4.交互式命令5.示例6.小结参考文献 1.简介 htop 是一种交互式、跨平台的基于 ncurses 的进程查看器。 类似于 top&#xff0c;但 htop 允许您垂直和水平滚动&#xff0c;并使用指向设备(鼠标)进行交互。您可以观察系统上运行的所有进程&#xff0…

关于支持向量机的一份介绍

在这篇文章中&#xff0c;我将介绍与支持向量机有关的东西&#xff0c;我们知道支持向量机主要分两类&#xff0c;就是线性支持向量机和核支持向量机这两种&#xff08;当然还有其他的&#xff0c;如多类支持向量机、 Nu-Support Vector Regression等&#xff09;&#xff0c;因…

docker存储

docker分层结构 如图所示&#xff0c;容器是由最上面可读可写的容器层&#xff0c;以及若干个只读镜像层组成&#xff0c;创建容器时&#xff0c;容器中的 数据都来自镜像层。这样的分层机构最大的特点是写时复制&#xff1a; 1、容器中新生成的数据会直接存放在容器层&#xf…

产品经理入门攻略:如何从零开始成为产品经理

“人人都是产品经理”这句话相信你一定听过。 作为现在的热门职业&#xff0c;许多朋友也在心里埋下了一颗想要成为产品经理的种子。 产品经理的工作其实没有传说中的那么“高大上”&#xff0c;甚至可以说大多数时候是枯燥且无聊的&#xff0c;需要不断地对数据进行分析&…

第十一章 【后端】商品分类管理微服务(11.5)——增强响应

11.5 增强响应 在前后端分离的开发模式下,我们一般会统一后端的响应格式,比如自定义 Response 结构,但每个开发者可能会封装各自的 Response 结构,造成不一致,因此我们需要将响应格式统一起来,定义一个统一的标准响应格式。 11.5.1 创建响应模块 新建 yumi-etms-respon…

高效实现业务流程管理的技术——低代码解决方案

一、低代码平台概述 低代码平台允许用户通过可视化的界面设计和配置应用程序&#xff0c;而无需深入编程知识。这种平台通常包括拖拽式的组件、流程图设计工具、以及预设的功能模块&#xff0c;使得业务用户和开发者都能快速构建和修改应用程序。 二、低代码平台在 BPM 中的优…

动手学深度学习PyTorch 第 1 章 引言

在线电子书 深度学习介绍 安装 使用conda环境 conda create -n d2l-zh python3.8 pip安装需要的包 pip install jupyter d2l torch torchvision下载代码并执行 wget https://zh-v2.d2l.ai/d2l-zh.zip unzip d2l-zh.zip jupyter notebookpip install rise如果不想使用jupyt…

ubuntu20.04安装cudnn

先登入账号 网址&#xff1a;https://developer.nvidia.com/cudnn 选择ubuntu20.04 x86_64&#xff08;Deb&#xff09; 在下载好文件的文件夹下打开终端 sudo apt-get install zlib1gsudo dpkg -i cudnn-local-repo-${distro}-8.x.x.x_1.0-1_amd64.debsudo cp /var/cudnn-lo…

【终极对决】Ping32 vs 绿盾:十大维度深度剖析,谁是企业数据安全的守护神?

在信息安全领域&#xff0c;企业对数据保护的需求不断升级。Ping32与绿盾加密作为两款备受关注的数据保护软件&#xff0c;各具特色。本文将从十大维度深度剖析这两款软件&#xff0c;帮助企业选择最适合自己的数据安全解决方案。 1. 加密算法 Ping32 Ping32采用了多种高级加…

Tiny Universe - Llama3架构

Llama3和Llama2和Qwen2的整体架构相似&#xff0c;本篇文章主要讲解它们的一些主要不同点。 关于Qwen2架构可参考 Qwen2架构 学习笔记 llama3区别于llama2在模型层面的区别主要体现在全模型使用GQA。 基础知识 MLP MLP&#xff08;Multi-Layer Perceptron&#xff09;多层感…

有毒有害气体检测仪的应用和性能_鼎跃安全

随着现代工业的不断发展和扩张&#xff0c;越来越多的企业涉及到有毒有害气体的生产、使用和处理。工业规模的扩大导致有毒有害气体的排放量增加&#xff0c;同时也增加了气体泄漏的风险。在发生火灾、爆炸或危险化学品泄漏等紧急事件时&#xff0c;救援人员需要迅速了解现场的…

生产管理电子看板如何助力工厂数字化转型

在当今快速发展的工业环境中&#xff0c;数字化转型已成为提升企业竞争力的关键因素之一。作为工厂管理的重要工具&#xff0c;生产管理电子看板在实现数字化转型方面发挥了不可或缺的作用。电子看板不仅优化了生产流程&#xff0c;还提高了决策效率&#xff0c;为企业带来了显…

什么是 IP 地址信誉?5 种改进方法

IP 地址声誉是营销中广泛使用的概念。它衡量 IP 地址的质量&#xff0c;这意味着您的电子邮件进入垃圾邮件或被完全阻止发送的可能性。 由于每个人都使用专用电子邮件提供商而不是直接通过 IP 地址进行通信&#xff0c;因此&#xff0c;这些服务可以跟踪和衡量发件人的行为质量…

heic图片怎么转化为jpg?教大家八种常见的heic转jpg方法!

heic图片怎么转化为jpg&#xff1f;谈及HEIC格式&#xff0c;这一新兴的图像编码方式以其卓越的压缩效率著称&#xff0c;它巧妙地运用了先进的编码技术&#xff0c;大幅缩减了图片占用的存储空间&#xff0c;然而&#xff0c;这枚科技果实也伴随着其独特的挑战&#xff0c;首要…

EMQX MQTT 服务器启用 SSL/TLS 安全连接,使用8883端口

1.提前下载安装openssl 2.新建openssl文件打开在命令行操作 3.按照下面的操作进行 MQTT 安全 作为基于现代密码学公钥算法的安全协议&#xff0c;TLS/SSL 能在计算机通讯网络上保证传输安全&#xff0c;EMQX 内置对 TLS/SSL 的支持&#xff0c;包括支持单/双向认证、X.509 证…

无法找到iutils.dll要怎么解决?四种修复iutils.dll的操作你知道么

当你收到“无法找到iutils.dll”的错误提示时&#xff0c;这表明你的系统缺失了一个关键的动态链接库文件&#xff0c;这可能阻止相关软件的正常启动和运行。面对这类问题&#xff0c;有多种方法可以帮助你追踪并恢复丢失的iutils.dll文件&#xff0c;从而使受影响的程序能够正…

Qt_布局管理器

目录 1、QVBoxLayout垂直布局 1.1 QVBoxLayout的使用 1.2 多个布局管理器 2、QHBoxLayout水平布局 2.1 QHBoxLayout的使用 2.2 嵌套的Layout 3、QGridLayout网格布局 3.1 QGridLayout的使用 3.2 设置控件大小比例 4、QFormLayout 4.1 QFormLayout的使用 5、…

基于Benes网络的SIMD同态密文任意重排

摘要 RLWE的密文使用了SIMD后极大的增加的同态加密的效率。同态加密通过加密一个向量&#xff0c;实现对明文的快速加法和乘法。然而&#xff0c;加密为一个密文的向量的内部元素之间&#xff0c;无法高效的操作。 如一个密文加密了 [ a , b , c ] [a,b,c] [a,b,c]&#xff0c…