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

2024-04-28 20:52
文章标签 反转 spring 究竟 控制 java

本文主要是介绍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/beanshttps://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的探索与实践,持续迭代中。

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

这篇关于Spring中控制反转究竟反转的什么的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/944238

相关文章

第一步->手撕spring源码之Bean容器创建

什么是bean容器 可以存放数据的具体数据结构实现,都可以称之为容器。例如:ArrayList、LinkedList、HashSet等。bean就是对象的定义 spring中bean的多样性需要区分就需要用到键值索引的场景 故选择 HashMap。 什么是hashMap? HashMap 是一种基于扰动函数、负载因子、红黑树转换等技术内容,形成的拉链寻址的数据结构,它能让数据更加散列的分布在哈希桶

【吊打面试官系列】Java高并发篇 - 同步方法和同步块,哪个是更好的选择?

大家好,我是锋哥。今天分享关于 【同步方法和同步块,哪个是更好的选择?】面试题,希望对大家有帮助; 同步方法和同步块,哪个是更好的选择? 同步块是更好的选择,因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会锁住整个对象,哪怕这个类中有多个不相关联的同步块,这通常会导致他们停止执行并需要等待获得这个对象上的锁。   同步块更要符合开放调用的原则,只在需要锁住的

Spring Boot应用部署 - JAR包部署瘦身

瘦身部署方案 说明 在日常开发测试环境中,随着业务代码的增加,Maven依赖的jar包也越来越多,导致工程包越来越大。通过阿里云流水线部署时,构建时长逐渐变得不够使用。为了解决这个问题,我们提出了以下瘦身部署方案。 执行 2.1 工程打包jar文件,解压取出非工程依赖的jar(BOOT-INF/lib) 在构建过程中,首先将工程打包为jar文件,然后解压该jar文件,取出其中的非工程依赖

面试经典算法系列之数组/字符串5 -- 反转字符串中的单词

面试经典算法题37-反转字符串中的单词 LeetCode.151 公众号:阿Q技术站 问题描述 给你一个字符串 s ,请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 **注意:**输入字符串 s中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的

【058】基于SpringBoot+Vue校园失物招领系统的设计与实现

系统介绍 基于SpringBoot+Vue校园失物招领系统主要通过使用Java语言编码设计系统功能,MySQL数据库管理数据,AJAX技术设计简洁的、友好的网址页面,然后在IDEA开发平台中,编写相关的Java代码文件,接着通过连接语言完成与数据库的搭建工作,再通过平台提供的Tomcat插件完成信息的交互,最后在浏览器中打开系统网址便可使用本系统。本系统的使用角色可以被分为用户和管理员,用户具有

【JVM】ASM开发

认识ASM ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。 ASM可以直接产生二进制class文件,也可以在类被加载入虚拟机之前动态改变类行为,ASM从类文件中读入信息后能够改变类行为,分析类信息,甚至能根据要求生成新类。 目前许多框架如cglib、Hibernate、Spring都直接或间接地使用ASM操作字节码。 ASM编程模型 1)Core API

【JVM】阅读Class字节码:常量池

目录 基本结构解析 常量池 常量池简介 如何阅读Class文件中的常量池信息 基本结构解析 Magic(魔数) Magic的唯一作用是确定这个文件是否为一个能被虚拟机所接受的class 文件。魔数值固定为0xCAFEBABE,不会改变。 常量池 常量池简介 下图是反编译过后的字节码文件中我们找到的常量池的部分。  可见常量池数量是从1到52,共52个常量,了

Springboot集成Netflix-ribbon、Enreka实现负载均衡-12

Netflix Ribbon简介 Netflix Ribbon是Netflix发布的云中间层服务开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。 具体来说,Ribbon是一个客户端负载均衡器,可以在配置文件中列出所有的服务提供方机器,然后Ribbon会自动基于某种规则(如简单轮询、随机连接等)去连接这些机器。同时,Ribbon也提供了一系列完善的配置项

【JavaEE】Maven简介与实用指南:项目构建和依赖管理的高效工具

目录 Maven什么是 Maven为什么学 Maven创建一个Maven项目依赖传递依赖排除 Maven 仓库本地仓库中央仓库私服 Maven设置国内源配置当前项⽬setting设置新项⽬的setting Maven 什么是 Maven 官⽅对于 Maven 的描述: Maven 是⼀个项⽬管理⼯具。基于 POM(Project Object Model,项⽬对象模

【全面介绍下Spring】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 🌈Spring 🌈Spring是一个开源的轻量级应用开发框架,它提供了一套全面的解决方案,用于构建企业级Java应用程序。Spring框架由一系列模块组成,每个模块都专注