【Java基础】Spring核心之控制反转(IOC)

news2024/12/26 11:03:41

1. 如何理解IOC

1.1 什么是IOC

在Spring框架中,IOC(Inversion of Control,控制反转)是一种设计原则,它是Spring框架的核心概念之一。IOC的基本思想是将程序的控制权从应用程序代码中转移到框架或容器中,从而实现了一种松耦合的设计。在IOC容器中,对象的创建、组装和管理都由容器来负责,而不是由程序员来手动管理对象之间的依赖关系。

在Spring中,IOC容器负责管理应用程序中的对象及其之间的关系。通过IOC容器,可以将对象之间的依赖关系通过配置文件或者注解来描述,然后由容器根据这些描述来创建和管理对象。这样一来,对象之间的耦合度就大大降低了,使得代码更加灵活、可维护、可测试。 IOC容器在Spring中通常是通过BeanFactory或者ApplicationContext实现的。

在这里插入图片描述
当有了IOC之后,就可以交给容器去做这些事情

在这里插入图片描述

1.2 IOC的作用

IOC的作用体现在以下三点:

  1. 松耦合: IOC能够降低组件之间的耦合度。在传统的编程模式中,对象的创建和依赖关系通常在代码中硬编码,导致组件之间高度耦合,一旦需要修改某个组件,可能会影响到其他组件。而通过IOC,对象的创建和依赖关系由容器负责管理,组件之间的依赖关系由配置文件或注解描述,使得组件之间解耦。
  2. 集中管理: IOC容器能够集中管理应用程序中的所有组件(Bean)。通过IOC容器,可以将所有组件的创建、配置、生命周期等统一管理,提高了组件的可维护性和可管理性。
  3. 简化代码: IOC能够减少大量样板式的代码,如对象的创建、依赖注入等。开发人员只需关注业务逻辑,而不需要关注对象的创建和管理,使得代码更加简洁清晰。
  4. 由于IOC能够降低组件之间的耦合度,使得单元测试变得更加容易。在测试时,可以通过替换特定的组件或者模拟依赖来进行单元测试,而不需要依赖于其他组件的具体实现。

2. IOC配置的方式

2.1 XML配置

首先,我们创建 UserRepository 接口和具体的实现类 UserRepositoryImpl:

// UserRepository.java
public interface UserRepository {
    void save(User user);
}

// UserRepositoryImpl.java
public class UserRepositoryImpl implements UserRepository {
    @Override
    public void save(User user) {
        // 实现保存用户的逻辑
    }
}

然后,我们创建 UserService 类,它依赖于 UserRepository:

// UserService.java
public class UserService {
    private UserRepository userRepository;

    // 构造函数注入
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void saveUser(User user) {
        userRepository.save(user);
    }
}

接下来,我们使用XML配置文件来配置Spring IOC容器,告诉Spring如何创建这些对象并建立它们之间的依赖关系:

<!-- applicationContext.xml -->
<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
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 配置UserRepository的实现类 -->
    <bean id="userRepository" class="com.example.UserRepositoryImpl" />

    <!-- 配置UserService,通过构造函数注入UserRepository -->
    <bean id="userService" class="com.example.UserService">
        <constructor-arg ref="userRepository" />
    </bean>
</beans>

2.2 Java配置

我们创建一个Java配置类来配置Spring IOC容器:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public UserRepository userRepository() {
        return new UserRepositoryImpl();
    }

    @Bean
    public UserService userService(UserRepository userRepository) {
        return new UserService(userRepository);
    }
}

在这个配置类中,我们使用 @Configuration 注解表明这是一个配置类。然后,我们使用 @Bean 注解来定义了 UserRepository 和 UserService 的Bean。对于 userService() 方法,我们通过参数注入了 UserRepository Bean。

最后,我们需要在应用程序中加载配置类并获取 UserService 实例:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = context.getBean(UserService.class);

        // 使用UserService保存用户
        userService.saveUser(new User("John", "Doe"));
    }
}

通过这种方式,我们使用Java配置类实现了IOC,Spring IOC容器会根据我们的配置类来创建和管理Bean。

2.3 注解配置

首先,我们不需要更改 UserService 和 UserRepository 的代码。接着,我们在 UserRepositoryImpl 类上添加 @Component 注解,将它声明为一个组件:

import org.springframework.stereotype.Component;

@Component
public class UserRepositoryImpl implements UserRepository {
    @Override
    public void save(User user) {
        // 实现保存用户的逻辑
    }
}

然后,我们在 UserService 类中使用 @Autowired 注解来自动注入 UserRepository:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    private UserRepository userRepository;

    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void saveUser(User user) {
        userRepository.save(user);
    }
}

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

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

相关文章

c#数据库: 4.修改学生成绩

将4年级的学生成绩全部修改为100分,。修改前的学生信息表如图所示: using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StudentUpdate {internal class Program{s…

C++:运算符重载-加号(+)

在C中&#xff0c;运算符重载允许重新定义已有运算符的行为&#xff0c;以便让它们适用于自定义类型。这样&#xff0c;你可以通过自定义类型使用内置运算符&#xff0c;使得代码更加直观和易读。 此时我在代码中定义一个新类MyString&#xff1a; class MyString { public:i…

MySQL常见问题解决和自动化安装脚本

常见问题 MySQL密码正确但无法登录的情况 这种情况一般都是因为缓存&#xff0c;使用mysql -u root -p123456直到成功登陆为止&#xff0c;并且进入之后重新修改密码&#xff0c;多次重复修改密码的命令并且再一次清除缓存后退出。 ALTER USER rootlocalhost IDENTIFIED WIT…

Microsoft Threat Modeling Tool 使用(二)

主界面 翻译 详细描述 选择了 “SDL TM Knowledge Base (Core)” 模板并打开了一个新的威胁模型。这个界面主要用于绘制数据流图&#xff08;Data Flow Diagram, DFD&#xff09;&#xff0c;它帮助您可视化系统的组成部分和它们之间的交互。以下是界面中各个部分的功能介绍&a…

CogAgent:开创性的VLM在GUI理解和自动化任务中的突破

尽管LLMs如ChatGPT在撰写电子邮件等任务上能够提供帮助&#xff0c;它们在理解和与GUIs交互方面存在挑战&#xff0c;这限制了它们在提高自动化水平方面的潜力。数字世界中的自主代理是许多现代人梦寐以求的理想助手。这些代理能够根据用户输入的任务描述自动完成如在线预订票务…

Bert基础(二十)--Bert实战:机器阅读理解任务

一、机器阅读理解任务 1.1 概念理解 机器阅读理解&#xff08;Machine Reading Comprehension, MRC&#xff09;就是给定一篇文章&#xff0c;以及基于文章的一个问题&#xff0c;让机器在阅读文章后对问题进行作答。 在机器阅读理解领域&#xff0c;模型的核心能力体现在对…

STM32使用PWM驱动直流电机

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 直流电机和驱动简介 2. 驱动电路原理 3. 代码实现 3.1 PWM.c 3.2 PWM.h 3.3 MOTOR.c 3.4 MOTOR.h 3.5 main.c 3.6 完整工程文件 PWM和OC输出比较详解&#xff1a; STM32定时器的OC比较和PW…

LT6911GX HDMI2.1 至四端口 MIPI/LVDS,带音频 龙迅方案

1. 描述LT6911GX 是一款面向 VR / 显示应用的高性能 HDMI2.1 至 MIPI 或 LVDS 芯片。HDCP RX作为HDCP中继器的上游&#xff0c;可以与其他芯片的HDCP TX配合使用&#xff0c;实现中继器功能。对于 HDMI2.1 输入&#xff0c;LT6911GX 可配置为 3/4 通道。自适应均衡功能使其适合…

使用Github+Picgo+npm实现免费图床

本文参考自 Akilar&#xff0c;原文地址&#xff1a;https://akilar.top/posts/3e956346/ Picgo的配置 Github图床仓库内容不能超过1GB&#xff0c;因为Github原则上是反对仓库图床化的&#xff0c;超过1GB之后会由人工审核仓库内容&#xff0c;如果仓库被发现用来做图床&…

简要说说软分叉和硬分叉。

前言 一、软分叉 二、硬分叉 三、用途 总结 前言 软分叉和硬分叉是区块链技术中的两个重要概念&#xff0c;它们通常与加密货币的网络升级有关。下面我将分别解释这两个概念&#xff0c;并提供一些例子来帮助理解。下面是方便理解软分叉和硬分叉的图 一、软分叉 软分叉是一…

docker学习笔记4:CentOS7安装docker

文章目录 一、安装docker二、配置阿里云加速三、测试镜像安装本篇博客介绍如何在centos7里安装docker,关于CentOS7的安装可以查看本专栏的这篇博客: VmWare CentOS7安装与静态ip配置 centos7里安装docker步骤如下: 一、安装docker 先在终端输入su进入root用户,输入如下命…

Outlook大附件插件 有效解决附件大小限制问题

很多企业都是使用Outlook来进行邮件的收发&#xff0c;可是由于附件大小有限&#xff0c;导致很多大文件发不出去&#xff0c;就会产生Outlook大附件插件这种业务需求。 邮件系统在发送大文件时面临的限制问题主要如下&#xff1a; 1、附件大小限制&#xff1a;大多数邮件服务…

操作系统课程设计-人机交互的模拟操作系统

&#xff08;一&#xff09;课设板块 模块划分&#xff1a; &#xff08;1&#xff09;、进程管理模块 &#xff08;2&#xff09;、内存管理模块 &#xff08;3&#xff09;、文件管理模块 &#xff08;4&#xff09;、设备管理模块 &#xff08;5&#xff09;、界面管理模块…

Elasticsearch中【文档查询】DSL语句以及对应的Java实现

目录 全文检索查询 精准查询 布尔查询 排序、分页查询 高亮 地理查询 复合查询 Elasticsearch提供了基于JSON的DSL&#xff08;Domain Specific Language&#xff09;来定义查询。常见的查询类型包括&#xff1a; 查询所有&#xff1a;查询出所有数据&#xff0c;一般测…

C语言:项目实践(贪吃蛇)

前言&#xff1a; 相信大家都玩过贪吃蛇这款游戏吧&#xff0c;贪吃蛇是久负盛名的游戏&#xff0c;它也和俄罗斯方块&#xff0c;扫雷等游戏位列经典游戏的行列&#xff0c;那贪吃蛇到底是怎么实现的呢&#xff1f; 今天&#xff0c;我就用C语言带着大家一起来实现一下这款游戏…

Springboot+Vue项目-基于Java+MySQL的校园疫情防控系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

达梦(DM) SQL聚集函数及日期运算操作

达梦DM SQL聚集函数及日期运算操作 聚集函数MAX、MIN、SUM、AVG、COUNT使用分析函数 sum (…) over (order by…) 可以生成累计和更改累计和的值计算出现次数最多的值 日期运算加减日、月、年加减时、分、秒日期间隔之时、分、秒日期间隔之日、月、年求两个日期间的工作天数确定…

《C语言深度解剖》(10):数组指针、指针数组和数组指针数组

&#x1f921;博客主页&#xff1a;醉竺 &#x1f970;本文专栏&#xff1a;《C语言深度解剖》《精通C指针》 &#x1f63b;欢迎关注&#xff1a;感谢大家的点赞评论关注&#xff0c;祝您学有所成&#xff01; ✨✨&#x1f49c;&#x1f49b;想要学习更多C语言深度解剖点击专栏…

抄表自动化的实现与优势

1.界定与简述 抄表自动化是一种当代关键技术&#xff0c;致力于取代传统的手动式抄表方法&#xff0c;通过远程数据数据采集解决&#xff0c;完成电力工程、水、气等公用事业电力仪表的全自动载入。这一系统利用先进的感应器、物联网技术(IoT)设备及数据数据分析工具&#xff…

2024年第十五届蓝桥杯江苏省赛回顾

呜呜呜~~~ 我在考完了后感觉自己直接炸了&#xff1a;好多学到的算法都没有用上&#xff0c;几乎所有的题目都是暴力的。。。 最后十几分钟对于一道dp算法终于有思路了&#xff0c;但是。。匆匆忙忙之间就是没有调试出来。&#xff08;还是交了一道暴力[旋风狗头]直接哭死~~&…