Spring IOC(一)

1. Spring IOC入门

1.1 什么是Spring IoC

        IoC(Inversion of Control),即控制反转,是一种设计原则。简单来说,IoC就是将程序的某种传统控制流程反转了。

        在Spring框架中,控制反转体现在对象的创建和管理上。

        在不使用Spring框架的情况下,程序中需要使用某个类的对象时,需要手动创建该对象,如下所示。

        基于Spring框架,开发者可以将类交给Spring框架管理,由Spring框架负责创建类的对象,并在开发者需要时提供给开发者。

1.2 Spring IoC容器概述

        Spring的IoC容器(IoC Container)是Spring框架的核心组件之一,负责管理对象的生命周期和依赖关系。它实现了IoC的概念,通过将对象的创建、依赖注入和销毁等任务从应用程序代码中转移到容器中,以实现更松耦合、可维护和可测试的应用程序。

        在Spring中,由IoC容器创建、组装和管理的对象被称为Bean。

1.3 第一个IoC示例

        本案例创建Maven项目,并在项目中引入Spring框架的依赖:

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.11</version>
</dependency>

        首先,创建com.obj.spring包,在包下新建ContextConfig类:

package com.obj.spring
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/*** Spring框架的配置类* 通过注解实现配置*/
@Configuration
@ComponentScan("com.obj.spring")
public class ContextConfig {
}

        接下来,声明com.obj.entity包,并在该包下创建Computer类。

package com.obj.entity;
import org.springframework.stereotype.Component;
@Component // 将当前类对象交给Spring框架管理
public class Computer {@Overridepublic String toString() {return "Computer{}";}
}

        然后,在com.obj包下创建案例的主类,命名为Application:

import com.obj.entity.Computer;
import com.obj.spring.ContextConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Application {public static void main(String[] args) {// 初始化Spring IoC容器对象ApplicationContext context =new AnnotationConfigApplicationContext(ContextConfig.class);// 通过Spring IoC容器对象获取Bean对象Computer computer = context.getBean(Computer.class);// 输出Bean对象信息System.out.println(computer);}
}

1.4 IoC示例运行原理解析

        ContextConfig是一个Spring框架的配置类,功能类似于xml配置文件,作用是为Spring框架提供用户自定义的配置。

        在早期的Spring框架中,配置是通过xml文件的方式提供的,内容较为繁琐。自2.5版本开始,Spring提供了基于注解进行配置的功能,可以更好的利用Java语言特性,避免了大量的XML配置代码。

  • @Configuration:用于标记当前类是一个Spring框架的配置类
  • @ComponentScan("cn.highedu"):用于通知Spring框架自动扫描和加载指定包下的所有组件并注册到Spring IoC容器中

        Computer是一个交给Spring管理的类。

  • @Component:用于将类标识为一个受Spring管理的组件

        ApplicationContext是Spring容器中最重要的核心接口之一,它扮演着Spring容器的角色,提供了一种对Spring Bean进行集中式管理的机制。

  • getBean方法用于从IoC容器中获取一个符合条件的Bean对象。

        AnnotationConfigApplicationContext是ApplicationContext接口的一个重要实现,它可以通过读取基于Java类的配置以及指定的Component classes来构建Spring IoC容器它在启动时将会扫描指定的包中所有用@Component@Service@Repository等注解修饰的类,将这些类实例化并且交由Spring容器进行管理。

1.5 IoC实现解耦示例

        本案例通过一个简单的耦合场景,演示Spring IoC为项目带来的好处。

        定义一个接口A和它的实现类B,然后定义20个类,分别命名为X1到X20。在X1到X20中都有一个名为method的方法,在方法中创建了B类的实例,并调用了run方法。

        此时,X1到X20与接口及其他实现类B存在依赖关系,即存在耦合。如下图所示:

        此时,有一个程序扩展需求:新建A接口的实现类C,将程序中所有的B类的对象都替换为C类的对象。为实现这一需求,需要逐个修改X1到X20类中的代码,程序的可扩展性和可维护性较差。

        如果项目中应用了Spring IoC,则可以极大的简化这一工作。

        首先,在com.obj.entity包下声明接口A。

public interface A {void run();
}

        然后,在com.obj.entity包下声明类B,类B实现接口A,并重写run方法:

import org.springframework.stereotype.Component;
@Component
public class B implements A{@Overridepublic void run() {System.out.println("Run by B");}
}

        在Application类中添加通过A接口类型获取Bean对象并测试的代码。

public class Application {public static void main(String[] args) {// 初始化Spring IoC容器对象ApplicationContext context =new AnnotationConfigApplicationContext(ContextConfig.class);A a = context.getBean(A.class);a.run();}
}

        此时,控制台输出“Run by B”。

        接下来,在cn.highedu.entity包下创建类C,同样实现A接口。

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
@Component
@Primary // 优先使用该类对象
public class C implements A{@Overridepublic void run() {System.out.println("Run by C");}
}

        再次运行Application类中的main方法,控制台输出“Run by C”,表示此时A接口的实现类已经改为使用类C。在这个切换的过程中,开发者并不需要对Application类中的代码进行修改,提高了程序的可扩展性。

1.6 Spring IoC的好处

        Spring IoC为项目带来许多好处:

        1、松耦合性: IoC降低了对象之间的紧密耦合度。对象不再直接创建和管理它们的依赖,而是通过容器来完成。这使得各个组件能够更独立地变化,降低了变更的风险。

        2、可维护性: 由于对象的创建和管理由容器负责,代码的结构更清晰,逻辑更集中。这使得代码更易于理解、扩展和维护,尤其在大型项目中尤为重要。

        3、灵活性: 通过配置文件或者注解,你可以在不修改代码的情况下改变对象的行为。这意味着你可以更容易地应对变化的需求,而不需要大规模的代码修改。

        4、重用性(Reusability): 通过依赖注入,对象可以被更广泛地重用。你可以通过将相同的组件配置到不同的环境中,实现代码的重用。

        总的来说,Spring IoC通过将控制权从应用程序代码中转移到容器中,带来了更好的可维护性、灵活性和重用性,有助于构建高质量、可扩展和易于维护的应用程序。

2. Spring DI入门

2.1 什么是DI

        在统一建模语言 (UML) 中,依赖(Dependency)是一种关系,表明一个元素或一组元素需要其他模型元素来进行规范或实现。

        DI是Dependency Injection的缩写,即依赖注入,是一项使一个对象接收到它所依赖的其他对象的技术。DI 的实现通常需要使用注解或 XML 配置文件来声明依赖关系:

2.2 Spring中的DI

        Spring框架提供了一种基于注解的、声明式的依赖注入方式,称为 Spring DI。

        DI是Spring框架实现控制反转(IoC)的一种方式,被反转的是一个对象获取其依赖对象的流程。

  • 传统流程:一个对象主动创建自己依赖项的对象
  • 反转后的流程:一个对象声明自己需要某个依赖项对象,由框架将依赖项对象注入到该对象中

        在 Spring 框架中,依赖注入通常通过注解或 XML 配置文件实现。

        1、注解方式

        Spring框架支持使用@Autowired、@Resources等注解来实现依赖注入。

  • @Autowired注解可以注入一个具体的类、接口、或者抽象类,一般用于注入当前对象依赖的其他对象
  • @Resources注解与@Autowired注解功能相似,但是执行机制上略有不同,推荐使用@Autowired注解

        2、XML配置文件方式(了解)

        Spring 框架也支持使用 XML 配置文件来实现依赖注入。通过 XML 配置文件,可以更清晰地定义依赖关系,同时也支持更多的配置选项。例如,可以使用以下 XML 配置文件来实现依赖注入:

<bean id="B"  class="com.example.demo.B">    
</bean>  
<bean class="com.example.demo.A">  <property name="b"  ref="B" />  
</bean>  

2.3 依赖注入示例

        在com.obj.entity包下声明Student类,该类包含一个Computer类型的属性。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class Student {// 通过Spring框架获取Computer对象@Autowiredprivate Computer computer;public void use(){System.out.println("使用电脑:"+computer);}
}

        在Application类的main方法中获取Student类的Bean,查看是否自动注入了Computer对象。

public class Application {public static void main(String[] args) {// 初始化Spring IoC容器对象ApplicationContext context =new AnnotationConfigApplicationContext(ContextConfig.class);Student student = context.getBean(Student.class);student.use();}
}

2.4 对Spring IoC和DI的理解

        1、Spring IoC的理解:

  • IoC即控制反转,是一种设计原则,它改变了传统的程序控制流程
  • 在Spring IoC中,不再是应用程序直接控制对象的创建和管理,而是将这些控制权交给了Spring容器
  • Spring IoC容器负责实例化对象、解决对象之间的依赖关系,并管理对象的生命周期
  • 这种反转的控制方式有助于实现松耦合、可维护和可复用的代码

        2、Spring DI的理解:

  • DI即依赖注入,是一项使一个对象接收到它所依赖的其他对象的技术
  • Spring框架提供了一种基于注解的、声明式的依赖注入方式,称为 Spring DI

        3、两者的关系

  • DI是Spring框架实现控制反转(IoC)的一种方式,被反转的是一个对象获取其依赖对象的流程
  • Spring的IoC容器是实现DI的基础

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

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

相关文章

jsp servlet 学生信息管理系统

一、角色划分 1、超级管理员 2、学生 二、模块展示 1、登录 2、列表页面【超级管理员展示所有用户信息、学生只展示当前登录用户信息】 3、新增 4、编辑 三、数据库【mysql】 四、运行演示 jsp servlet 学生信息管理系统

rust疑难杂症解决

rust疑难杂症解决 边碰到边记录&#xff0c;后续可能会逐步增加&#xff0c;备查 cargo build时碰到 Blocking waiting for file lock on package cache 原因是Cargo 无法获取对包缓存的文件锁&#xff0c; 有时vscode中项目比较多&#xff0c;如果其中某些库应用有问题&…

CSS 之 transition过渡动画

一、简介 ​ CSS 制作 Web 动画有两种方式&#xff1a; 帧动画&#xff08;Keyframe Animation&#xff09;和过渡动画&#xff08;Transition Animation&#xff09;。针对不同的业务场景中&#xff0c;我们应该选择不同的动画方式&#xff0c;通常来说&#xff1a;对于交互元…

vue3插槽的name和v-slot的研究

slot可以分为具名插槽和默认,默认插槽name是default 在父组件的template需要些v-slot/#,没写不生效,而在父组件下,而没被template包含的默认放在template且含有#default. 1)没写slot,可以不写template,也可写default的template2)写了name的slot,即使是default也必须些template…

STM32G431RBT6之LCD与LED配置

首先,配置时钟树,时钟树的配置在我的另外一篇博客里,这里不再赘述. LCD与LED具有共同的IO口,同时创建工程较好. 打开原理图,发现LED的IO口是PC8~PC15,还有一个容易看漏的PD2.LCD的IO口是PC0到PC15. 当然,看产品手册也可以知道,但是还是推荐大家看原理图. 打开cubumx,给PC0~PC…

Java设计模式 _结构型模式_过滤器模式

一、过滤器模式 1、过滤器模式 过滤器模式&#xff08;Filter Pattern&#xff09;是这一种结构型设计模式。过滤器&#xff0c;顾名思义&#xff0c;就是对一组数据进行过滤&#xff0c;从而最终获取到我们预期的数据。 2、实现思路 &#xff08;1&#xff09;、定义过滤器的…

想要应聘前端工程师——学习路线指南

前端工程师学习路线 按照前端岗位需求,以优先学习工作更需要,面试更常考的内容为原则,由浅入深,层层铺垫,与时俱进,可以较容易地总结出前端学习路线图: HTML / CSS / JavaScript 基础学习 《Web 入门》 MDN 权威入门指南,HTML / CSS / JavaScript 快速上手 《CSS 世界…

华为OD机试 - 密码解密(Java 2024 C卷 100分)

华为OD机试 2024C卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;每一题都有详细的答题思路、详细的代码注释、样例测试…

ChatGPT/GPT4 科研实战教程-包括论文写作、数据分析、科研绘图、PPT制作,程序开发

从2022年3月&#xff0c;OpenAI公司发布chatGPT3.5开始&#xff0c;以ChatGPT为代表的人工智能内容生成技术&#xff08;简称AIGC&#xff09;引起了广泛关注&#xff0c;我们进入了全民AI时代。 因此&#xff0c;我们需要了解和掌握AI思维&#xff0c;才能更好适应这个时代的…

uniapp微信小程序-分享

https://developers.weixin.qq.com/miniprogram/dev/component/button.html https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share.html#%E4%BD%BF%E7%94%A8%E6%8C%87%E5%BC%95 参考未整理 自定义参考未整理

使用Canal实现MySQL主从同步

说明&#xff1a;本文介绍如何使用Canal实现MySQL主从同步的效果&#xff0c;关于Canal入门使用参考&#xff1a;Canal入门使用 启动Canal 首先&#xff0c;设置Canal服务器里&#xff0c;目标节点&#xff08;即监测的MySQL节点&#xff09;的配置&#xff0c;启动Canal服务…

Scala 03 —— Scala OOP Extension

Scala 2.1 —— Scala OOP Extension 一、正则 文章目录 Scala 2.1 —— Scala OOP Extension一、正则1.1 Java正则和Scala正则的区别1.2 Java正则和Scala正则的的基本知识点Java正则Scala正则 1.3 练习练习一&#xff1a;使用正则表达式解析日志方法一&#xff1a;使用findAl…

心理学上有个概念叫:习惯性反驳(附上解决办法)

在心理学上&#xff0c;有一个词&#xff0c;叫做习惯性反驳。 什么意思呢&#xff1f; 就是不管你说什么&#xff0c;他都要反驳你&#xff0c;最后把你带入负面的情绪黑洞&#xff0c;搞得你非常崩溃。 一个总是习惯性反驳的人&#xff0c;其实是非常可怕的。 习惯性反驳的3个…

与Apollo共创生态:Apollo7周年大会自动驾驶生态利剑出鞘

前言 4月22日&#xff0c;百度Apollo在北京车展前夕举办了以“破晓•拥抱智变时刻”为主题的智能汽车产品发布会&#xff0c;围绕汽车智能化&#xff0c;发布了智驾、智舱、智图等全新升级的“驾舱图”系列产品。 1、7周年大会 自2013年百度开始布局自动驾驶&#xff0c;201…

PotatoPie 4.0 实验教程(24) —— FPGA实现摄像头图像中心差分变换

为什么要对图像进行中心差分变换&#xff1f; 对图像进行中心差分变换的主要目的是计算图像中每个像素点的梯度。梯度在图像处理中是一个非常重要的概念&#xff0c;它可以用来描述图像中灰度变化的快慢和方向&#xff0c;常用于边缘检测、特征提取和图像增强等任务中。 具体…

windows服务启动提示‘服务没有响应控制功能’(mysql启动报错)

在安装mysql的时候&#xff0c;在windows服务项启动 或 使用命令net start mysql 时启动是报错&#xff0c;提示 服务没有响应控制功能 发生原因&#xff1a; Windows10 x64 或 更高的操作系统&#xff0c;有些系统缺少一些组件 解决办法&#xff1a; 1、下载最新的 Microsoft …

clickhouse安装部署

虚拟机&#xff1a;virtualbox7.0 操作系统&#xff1a;ubuntu server 22.04.3 虚拟机硬件&#xff1a;cpu 1&#xff0c;内存 2G&#xff0c; 硬盘 100G 采用默认安装 参照 https://clickhouse.com/docs/en/install#quick-install 安装部署 对于Debian、Ubuntu&#xff0c…

版本比对sql

弹窗 index <template><el-dialogtitle"版本":visible.sync"dialogVisible"width"55%"center:close-on-click-modal"false":close-on-press-escape"false":before-close"beforeClose"open"open&q…

【Linux网络】DHCP原理与配置

目录 一、DHCP工作原理 1.了解DHCP服务 2.使用DHCP的好处 3.DHCP的分配方式 二、DHCP的租约过程 三、DHCP场景应用实验 一、DHCP工作原理 1.了解DHCP服务 DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机配置协议&#xff09; 由Internet工作…

【MyBatis】使用MyBatis框架在两张表是一对多的情况下,进行分步查询,发现对查询出来的结果进行封装时没有将实体类的id进行赋值

Catalog MyBatis在两张表是一对多的情况下,进行分步查询&#xff0c;发现对查询出来的结果进行封装时没有将实体类的id进行赋值1. 表结构2. 场景3. 实现方式具体步骤 4 .测试5. 解决方法 MyBatis在两张表是一对多的情况下,进行分步查询&#xff0c;发现对查询出来的结果进行封装…