Spring中控制反转究竟反转的什么

你好,这里是codetrend专栏“Spring6全攻略”。

控制反转(Inversion of Control, IoC)是一种软件设计原则,它将传统的程序设计中的控制权从应用程序代码转移到框架或容器,从而实现了松耦合和更好的可维护性。

在控制反转的概念中,应用程序的组件不再负责自己的创建和管理,而是交给外部容器来负责。这样做的好处是降低了组件之间的依赖关系,提高了代码的灵活性和可测试性。

Spring框架是一个经典的IoC容器,它通过依赖注入(Dependency Injection, DI)的方式实现了控制反转。在Spring中,开发者只需要定义组件及其依赖关系,而框架负责实例化和管理这些组件,将依赖关系注入到需要的地方。

依赖注入(Dependency Injection, DI)是IoC的一种专门形式,其中对象仅通过构造函数参数、工厂方法参数或在对象实例被构建后设置的属性来定义它们的依赖关系(即与之协同工作的其他对象)。接着,在创建bean时,IoC容器会注入这些依赖项。这一过程本质上是对bean自身直接控制其依赖项的实例化或定位方式的反转(因此得名“控制反转”),通常采用直接构造类或类似服务定位器模式的机制。

整个过程用mermaid流程图表示如下:

应用程序
IoC容器
创建Bean
实例化Bean
解析依赖关系
依赖注入
通过构造函数参数或工厂方法参数或属性设置注入依赖项
使用服务定位器等机制定位依赖项

org.springframework.beansorg.springframework.context 包构成了Spring框架IoC容器的基础。关于IoC的代码实现都是放在这里面的。

BeanFactory 接口提供了一个高级配置机制,能够管理任何类型的对象。而ApplicationContextBeanFactory 的一个子接口,并增加了以下功能:

  • 更易于集成Spring的AOP特性
  • 消息资源处理(用于国际化)
  • 事件发布
  • 应用层特定上下文,例如Web应用程序中使用的WebApplicationContext

简而言之,BeanFactory 提供了配置框架和基本功能,而ApplicationContext 则扩展了更多企业级特有的功能。ApplicationContext 完全包含了BeanFactory 的所有功能。

在Spring中,构成应用程序核心并由Spring IoC容器管理的对象被称为bean。

bean是由Spring IoC容器实例化、组装和管理的对象。除此之外,bean只是应用中的众多对象之一。bean及其之间的依赖关系体现在容器所使用的配置元数据中。

SpringBean的历史渊源

Jakarta EE中定义了一个Enterprise Beans。由于Spring6框架和Jarkata EE中的规范是息息相关的,通过对比的方法来一探究竟。

Spring Bean 是指在Spring框架中由IoC容器管理的对象实例,也被称作“Spring组件”。这些Bean构成了应用程序的主要部分,负责承载业务逻辑和服务功能。

Spring Bean的特点如下:

  • 容器管理:Spring IoC(控制反转)容器负责Bean的生命周期管理,包括创建、初始化、装配依赖、销毁等一系列操作。
  • 依赖注入:Bean之间的依赖关系通过依赖注入(Dependency Injection,DI)来建立,容器负责将所需的依赖项注入到Bean中,而不是由Bean自身去寻找或创建这些依赖。
  • 配置元数据:Spring Bean的定义和配置信息通常存储在XML配置文件、Java配置类或者注解中,这些配置元数据指导了IoC容器如何创建和管理Bean。
  • 作用域:Spring Bean有多种作用域,如Singleton(单例)、Prototype(原型)、Request、Session、Application和WebSocket等,不同的作用域决定了Bean实例在应用程序中的创建和共享策略。
  • 生命周期:Spring Bean拥有完整的生命周期,允许开发者通过实现特定的接口(如InitializingBean、DisposableBean或使用@PostConstruct/@PreDestroy注解)来自定义初始化和销毁逻辑。
  • 可扩展性:通过BeanPostProcessor和FactoryBean等扩展点,可以进一步自定义Bean的创建过程和行为。
  • 松耦合:通过依赖注入实现松耦合,使得各组件间相互独立,更容易维护和替换。
  • 面向切面编程(AOP):Spring Bean能够无缝地与Spring的AOP机制相结合,支持诸如事务管理、日志记录、权限检查等横切关注点的统一处理。
  • 自动装配:Spring支持自动装配功能,可以通过@Autowired注解或其他机制自动匹配并注入相应的依赖服务。

Jakarta EE 中的EJB(Enterprise JavaBeans)是一种用于开发企业级分布式应用程序的标准组件模型,它为开发人员提供了封装业务逻辑并在多个客户端之间复用的能力。

EJB主要具有如下特点:

  • 容器管理:EJB运行在EJB容器中,容器负责管理Bean的生命周期、安全、事务、并发、资源池化等非功能性需求,减轻了开发者的工作负担。
  • 事务管理:EJB提供全面的事务支持,包括全局事务(Global Transactions)和局部事务(Container-Managed Transactions, CMT),能够跨多个数据库或消息队列资源进行事务管理。
  • 安全性:EJB容器支持基于角色的安全性,开发者可以在EJB级别定义访问控制策略,确保只有授权用户或角色才能访问特定的业务服务。
  • 消息驱动:消息驱动Bean可以监听JMS(Java Message Service)消息,实现异步处理和解耦,适用于高性能的消息传递场景。
  • 持久化支持:实体Bean特别设计用于映射数据库表,提供了ORM(对象关系映射)的功能,使得业务对象可以自动持久化至数据库。
  • 远程访问:EJB支持远程调用,客户端可以通过RMI(Remote Method Invocation)协议访问部署在服务器上的EJB组件。

与Spring6框架对比,EJB的一些复杂性和重量级特性逐渐显得过重,尤其是在易用性、测试友好度以及性能方面。

Spring6通过提供更为简洁的编程模型和灵活的事务管理等功能,一定程度上替代了EJB在某些场景下的应用。

Spring6通过组件项目的方式提供了对EJB的替代。Spring只提供最基础的核心功能。比如spring-jms用于与 JMS(Java Message Service)消息队列的集成、 spring-tx提供了对事务管理的支持。

所以Spring6的设计在于轻量级、组件可选的方式来完成了一个又一个企业级应用的搭建。

说说什么是SpringBean

Spring IoC容器管理一个或多个bean。这些bean是根据您提供给容器的配置元数据创建的(例如,以XML <bean/> 定义的形式)。

在容器内部,这些bean定义被表示为BeanDefinition对象,其中包含(除其他信息外)以下元数据:

  • 带包限定名的类名:通常是指定bean的实际实现类。
  • Bean行为配置元素,描述了bean在容器中应该如何表现(作用域、生命周期回调等)。
  • 对于bean完成其工作所必需的其他bean的引用。这些引用也被称为协作者或依赖项。
  • 其他配置设置,用于在新创建的对象上设置属性——例如,在管理连接池的bean中设置池大小限制或使用连接数。

这些元数据转换成构成每个bean定义的一组属性。下表描述了这些属性:

属性描述章节
Class实例化Bean
Name命名Bean
ScopeBean作用域
Constructor arguments依赖注入
Properties依赖注入
Autowiring mode自动装配协作者
Lazy initialization mode懒加载Bean
Initialization method初始化回调
Destruction method销毁回调

表1. Bean定义属性

通过Bean定义属性这张表格可以看出Bean的全景图,而Spring6基于此提供了一个完整的实现方案。

除了包含创建特定bean所需信息的bean定义之外,ApplicationContext实现还允许注册由用户在容器外部创建的现有对象。这通过访问ApplicationContext的BeanFactory来实现,即调用getBeanFactory()方法,该方法返回DefaultListableBeanFactory实现。DefaultListableBeanFactory通过registerSingleton(..)registerBeanDefinition(..)方法支持这种注册功能。然而,典型的应用程序通常仅使用通过常规bean定义元数据定义的bean。

注意:bean元数据和手动提供的单例实例需要尽早注册,以便容器在自动装配和其他内省步骤中正确地解析它们。

虽然在一定程度上支持覆盖现有元数据和现有单例实例,但在运行时(与对工厂的实时访问同时)注册新的bean并未得到官方支持,这可能会导致并发访问异常、bean容器状态不一致,或者两者兼有。

说说 Spring IoC容器

org.springframework.context.ApplicationContext 接口代表了Spring的IoC(控制反转)容器,并负责bean的实例化、配置和组装。该容器通过读取配置元数据获取关于需要实例化、配置和组装哪些对象的指令。

这些配置元数据可以以XML、Java注解或Java代码的形式表示,它允许你明确表达组成应用程序的对象以及这些对象之间的丰富依赖关系。

Spring提供了多个ApplicationContext接口的实现版本。在独立应用程序中,通常会创建一个ClassPathXmlApplicationContextFileSystemXmlApplicationContext实例。

尽管XML是定义配置元数据的传统格式,但可以通过提供少量XML配置来声明性地启用对Java注解或代码作为元数据格式的支持,从而指导容器使用这些额外的元数据格式。

以下mermaid流程图简单展示了Spring工作过程。业务类与配置元数据相结合,使得在Spring容器ApplicationContext被创建并初始化后,得到的是一个完全配置好且可执行的系统或应用程序。

产生
业务类POJO
Spring容器ApplicationContext
配置元数据Configuration Metadata
可执行的系统/应用程序

说说配置元数据(Configuration Metadata)

Spring的Configuration Metadata是指一组用于描述和指导Spring IoC(控制反转)容器如何创建、配置和装配应用中各个对象(即所谓的“bean”)的信息。这种元数据传统上是以一种直观且简洁的XML格式提供的,但也可以采用Java注解或纯Java代码的形式表示。

Configuration Metadata包含了如下关键信息:

  • Bean定义: 对象的类型、名称、构造器参数、属性值和依赖关系等,这些信息告诉Spring容器如何实例化对象。
  • 装配指示: 如何将一个bean与其他bean关联起来,包括设置属性值、引用其他bean、注入集合元素等。
  • 生命周期回调方法: 定义在bean的生命周期中何时调用特定的方法,例如初始化后(@PostConstruct)或销毁前(@PreDestroy)。
  • 容器配置: 容器自身的配置,如自动扫描哪些包以发现组件、启用特定的特性(如自动装配或AOP代理)等。

在XML配置文件中,配置元数据表现为<bean>元素及其内部属性和嵌套元素;在Java配置中,配置元数据则通过标注了@Configuration的类以及标注了@Bean的方法来定义。

Spring Configuration Metadata是程序员向Spring IoC容器传达应用程序对象结构和依赖关系的蓝图,是Spring框架动态装配和管理对象的基础。通过解析和应用这些配置元数据,Spring IoC容器能够在运行时生成一个完全配置好并准备就绪的应用程序对象图。

以下是一个基于xml的Spring配置文件的示例:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- services -->
	<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
		<property name="accountDao" ref="accountDao"/>
		<property name="itemDao" ref="itemDao"/>
		<!-- additional collaborators and configuration for this bean go here -->
	</bean>
	<!-- more bean definitions for services go here -->
</beans>

关于作者

来自一线全栈程序员nine的探索与实践,持续迭代中。

欢迎关注或者点个小红心~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mysql索引失效情况

索引失效的情况 这是正常查询情况&#xff0c;满足最左前缀&#xff0c;先查有先度高的索引。 1. 注意这里最后一种情况&#xff0c;这里和上面只查询 name 小米科技 的命中情况一样。说明索引部分丢失&#xff01; 2. 这里第二条sql中的&#xff0c;status > 1 就是范围查…

性能超越!新模型Dragoman打造高质量英译乌翻译系统,打败现有SOTA模型

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;探索乌克兰语的机器翻译挑战 在当今全球化迅速发展的背景下&#xff0c;机器翻译技术已成为沟通世界各地文化和语言的重要桥梁。尽管如此&…

【Axure高保真原型】动态伸缩信息架构图

今天和大家分享动态伸缩信息架构图的原型模板&#xff0c;我们可以通过点击加减按钮来展开或收起子内容&#xff0c;具体效果可以点击下方视频观看或者打开预览地址来体验 【原型效果】 【Axure高保真原型】动态伸缩信息架构图 【原型预览含下载地址】 https://axhub.im/ax9/…

Python从0到100(二十):文件读写和文件操作

一、文件的打开和关闭 有了文件系统可以非常方便的通过文件来读写数据&#xff1b;在Python中要实现文件操作是非常简单的。我们可以使用Python内置的open函数来打开文件&#xff0c;在使用open函数时&#xff0c;我们可以通过函数的参数指定文件名、操作模式和字符编码等信息…

关于蓝队应急响应工具箱意见征集

前言 征集一下各位师傅的意见&#xff0c;没用过的师傅可以去以往的文章下载使用&#xff1a; 下载地址&#xff08;有个小小改动&#xff0c;去除了必要的python环境&#xff0c;使其占用空间更小&#xff09;&#xff1a; [护网必备]知攻善防实验室蓝队应急响应工具箱v202…

自动化运维工具---Ansible

一 Puppet Puppet是历史悠久的运维工具之一。它是一种基础架构即代码(laC)工具&#xff0c;使用户可以定义其基础 架构所需的状态&#xff0c;并使系统自动化以实现相同状态。 Puppet可监视用户的所有系统&#xff0c;并防止任何偏离已定义状态的情况。从简单的工作流程自动…

pytest教程-36-钩子函数-pytest_collection_start

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_unconfigure钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_collection_start钩子函数的使用方法。 pytest_collection_start(session) 是一个 pytest 钩子函数&#xff0c;…

YOLO-World环境搭建推理测试

一、引子 CV做了这么多年&#xff0c;大多是在固定的数据集上训练&#xff0c;微调&#xff0c;测试。突然想起来一句话&#xff0c;I have a dream&#xff01;就是能不能不用再固定训练集上捣腾&#xff0c;也就是所谓的开放词汇目标检测&#xff08;OVD&#xff09;。偶尔翻…

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup

new mars3d.control.MapSplit({实现点击卷帘两侧添加不同图层弹出不同的popup效果&#xff1a; 左侧&#xff1a; 右侧&#xff1a; 说明&#xff1a;mars3d的3.7.12以上版本才支持该效果。 示例链接&#xff1a; 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 相关代…

C++进阶:AVL树

AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但 如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查 找元素相当于在顺序表中搜索元素&#xff0c;效率低下 。因此&#xff0c;两位俄罗斯的数学家 G.M. A delson- V elskii 和 E.M. L andis 在 1962 …

如何确定Unity/VNXe存储的主控制器(Primary SP)

DELL EMC的Unity或者VNXe存储都是双控的架构&#xff08;VNXe 1代设备有部分支持单控配置&#xff09;&#xff0c;有些的CLI检查命令是必须在primary SP&#xff0c;也就是主控制器上执行的&#xff0c;那么问题来了&#xff0c;如何确定两个控制器中那个是主控制器呢&#xf…

FreeRTOS资源管理

1.以前临界资源的保护方式 有使用过静态局部变量来保护临界资源&#xff0c;也有用队列&#xff0c;信号量&#xff0c;互斥量来保护临界资源。这些都是在多个任务会共同使用临界资源的情况下我们的保护方式。 问题提出&#xff1a;如果有个传感器在读取数据时有严格的时序&a…

使用idea编辑器回退git已经push的代码

直接上结果 选择想要回退的那次/多次提交历史, 右击, 选中 revert commit git自动产生一个Revert记录&#xff0c;然后我们会看到git自动将我第三次错误提交代码回退了&#xff0c;这个其实就相当于git帮我们手动回退了代码。 后续&#xff0c;只需要我们将本次改动push到远…

js之DOM 文档对象模型

当网页被加载时&#xff0c;浏览器会创建页面的文档对象模型&#xff08;Document Object Model&#xff09;&#xff0c;简称 DOM。DOM 模型被结构化为对象树&#xff0c;又称DOM 树。 DOM 实际上是以面向对象方式描述的对象模型&#xff0c;它将文档建模为一个个对象&#xf…

ChatGPT的真实能力如何?七大NLP任务一探究竟!

文章链接&#xff1a;https://arxiv.org/pdf/2405.00704 ChatGPT已经改变了人工智能社区&#xff0c;一个活跃的研究方向是ChatGPT的性能评估。评估的一个关键挑战是ChatGPT仍然是闭源的&#xff0c;传统的基准数据集可能已被ChatGPT用作训练数据。在本文中: 调查了最近的研究…

Linux 内核的操作系统确实需要一直运行

在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「 Linux的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 但是这并不是调度的基础。每…

【1小时掌握速通深度学习面试6】图神经网络-下

目录 23. GraphSage 24.简述图神经网络的推理机制在其他领域中的应用 与传统NN的区别&#xff08;GNN优点&#xff09; 23. GraphSage GraphSage出现之前的图网络方法需要图中所有的顶点在训练embedding的时候都出现&#xff0c;这些的方法本质上是transductive&#xff0c…

字节上岸成功,整理一波测试开发岗的基础知识,含答案

本科非科班&#xff0c;去年秋招找非技术岗工作失败&#xff08;无法通过群面&#xff09;。谁又能想到今年春招形势严峻比去年秋招还严峻…. 太难了&#xff01;&#xff01;&#xff01;&#xff01; 2月末开始投简历&#xff0c;3月份开始面了tplink、字节、美团、广立微电…

自编码器网络

1.自编码器网络 自动编码器是一种无监督的数据维度压缩和数据特征表达方法。 无监督 在海量数据的场景下&#xff0c;使用无监督的学习方法比有监督的学习方法更省力。 维度上的压缩 自编码网络可以根据输入的数据&#xff0c;对其进行表征学习。输入数据转换到隐藏层co…

简单介绍IIC通信协议

文章目录 一&#xff0c;简单介绍二&#xff0c;IIC物理层三&#xff0c;IIC通信时序1.起始位与停止位2.IIC读写地址位信号3.IIC应答信号4.IIC数据位收发信号 四&#xff0c;总线速率五&#xff0c;主机发送数据流程六&#xff0c;主机接收数据流程七&#xff0c;IIC的时钟延展…
最新文章