Spring DIIoC

news2025/4/21 8:25:49

一.IoC

1.简介

什么是IoC?IoC,全称 Inversion of Control,控制反转。IoC是Spring的核心思想,Spring是⼀个“控制反转”的容器。

如果我们需要一个对象,正常来说我们是通过new一个对象,这个时候我们依赖的是new的这个对象。在Spring中,我们可以将一个类放入Spring,让Spring帮我们new这个类,我们自己就不用管 了,要用的时候只需要依赖注入(DI)即可。通过这个,我们也实现了对代码的解耦。

Spring提供了两类注解可以实现将对象放入容器管理这个目的:

1)类注解:@Controller@Service@Repository@Component@Configuration

2)方法注解:@Bean

2.获取Bean对象

我们能将对象放入容器中,也能将容器取出来。我们先获取Spring上下文对象,再使用上下文对象来获取到Bean对象。

Spring上下文(Spring context),是 Spring 框架的核心概念之一,它是一个容器,负责管理应用程序中的 Bean 对象及其生命周期,同时还提供了许多其他的功能(源代码中有详细介绍)。

getBean这个方法提供了五种方式:

第一种是使用 类的类型,第二种使用 Bean名 和 类的类型,第三种使用 类的类型 和 构造函数参数,第四种使用 Bean名,第五种使用 类名 和 构造函数参数。

这里举几个例子:

ApplicationContext context=SpringApplication.run(Springdemo03Application.class, args);
//Hello是个类
Hello hello1=context.getBean(Hello.class);
Hello hello2= (Hello) context.getBean("hello");

这里要注重强调一个点,就是这个Bean名。这个Bean名不是类的名称,而是有其独特的命名。

Bean名的命名规则如下:对于一般类名,Bean以小写字母开头,然后使用驼峰式大小写;如果类名有多个字母,并且第一个和第二个字母为大写,那么Bean名与类名相同。

例如:UserController --> userController     UController --> UController。

我们通过这个方法获取的相同名称或类型的Bean,这些Bean对象都是同一个。

3.类注解

将这些注解加到类上,表示这个类被放入容器中啦。

1)@Controller(控制器存储)

@Controller:控制层,接收请求,对请求进行处理,并进行响应

@Controller
public class UserController {
    public String name;
}

2) @Service(服务存储)

@Servie:业务逻辑层,处理具体的业务逻辑

@Service
public class UseServicer {
    public String name;
    public void print(){
        System.out.println(name);
    }
}

3) @Repository(仓库存储)

@Repository:数据访问层,也称为持久层。负责数据访问操作

@Repository
public class UserRepository {
    public String name;
    public void print(){
        System.out.println(name);
    }
}

4)@Component(组件存储)

@Component
public class UserComponent {
    public String name;
    public void print(){
        System.out.println(name);
    }
}

5)@Configuration(配置存储)

@Configuration:配置层,处理项目中的⼀些配置信息

@Configuration
public class UserConfiguration {
    public String name;
    public void print(){
        System.out.println(name);
    }
}

 6)总结

打开上述注解的源码,我们会发现它们中都有 @Component 这个注解。上述注解其实是 @Component 这个注解的衍生注解,而我们对这些注解进行拆解的原因是方便更好的分层。

4.方法注解

方法注解,顾名思义,就是加在方法上的注解。使用方法注解主要是为了解决这两个问题,一是使用外部包的类没办法添加类注解,二是一个类可能需要多个对象。

这里要注意,使用@Bean,这个方法所属的类必须加上类注解。

@Service
public class Hello {
    @Bean
    public User user(){
        User user=new User();
        user.name="111";
        return user;
    }
}

那如何实现同一个类注入多个对象呢?很简单,写两个不就行了。但是,当我们运行的时候就会发现报错了:required a single bean, but 2 were found.

这个报错告诉我们:这个容器里面有两个对象,它也不知道该用哪个。

方法一:我们在通过Spring上下文获取Bean的时候使用Bean名来获取;

方法二:重命名,对Bean进行重命名,这个名可以写一个,也可以写多个

//@Bean("u1")
@Bean(name = {"u1","u3"})
public User user1(){
    User user=new User();
    user.name="111";
    return user;
}

二.DI

1.简介

什么是DI?DI,全称 Dependency Injection,依赖注入。什么是依赖注入?容器在运行期间,动态的为应用程序提供运行时所依赖的资源。可以理解成我们可以从容器中取出放入容器中的类。

2.注入方法

1)属性注入(Field Injection)

我们通过 @Autowired 这个注解来实现属性注入,实现起来相当简单,一行就解决了。

优点:简洁,使用方便。

缺点:只能用于IoC容器;不能输入Final修饰的属性。

@Controller
public class HelloController {
    @Autowired
    public User user;
    public void print(){
        user.print();
    }
}

2)构造方法注入(Constructor Injection)

将 @Autowired 这注解加在构造方法上,构造方法上的这个user就是从容器中取的。

优点:可以注入final修饰的属性;注入的对象不会被修改;依赖对象在使用前一定会被完全初始化;通用性好。

缺点:注入多个对象,处理起来比较麻烦。

@Controller
public class HelloController {
    public User user;
    @Autowired
    public HelloController(User user){
        this.user=user;
    }
    public void print(){
        user.print();
    }
}

3)Setter注入(Setter Injection)

将 @Autowired 这个注解加在setter方法上,setter方法上的user就是从容器中取的。

优点:方便在类实例化后重新对该对象进行配置或者注入。

缺点:不能注入final修饰的属性;注入对象可能被改变。

@Controller
public class HelloController {
    public User user;
    @Autowired
    public void setUser(User user) {
        this.user = user;
    }
    public void print(){
        user.print();
    }
}

3.Bean不唯一

上面的代码都是建立在同一个类只有一个对象放入了容器中,那如果同一个类有多个对象呢?

1)@Primary

@Primary 可以确认一个默认的实现,也就是说可以指定一个类,我就取这个类,就是这个意思。

@Service
public class Hello {
    public void print(){
        System.out.println("hello world");
    }
    @Bean
    @Primary
    public User user1(){
        User user=new User();
        user.name="111";
        return user;
    }
    @Bean
    public User user2(){
        User user=new User();
        user.name="222";
        return user;
    }
}

2)@Qualifier

@Qualifier 可以指定当前要注入的对象,这个注解的用法跟上面的 @Primary 其实正好相反(代码可以看出)。@Qualifier 是加在要注入的对象上的,@Qualifier 必须要与 @Autowired 一起使用。

@Controller
public class HelloController {
    @Autowired
    @Qualifier("user1")
    public User user;
    public void print(){
        user.print();
    }
}

3)@Resource

@Resource 是按照Bean的名称进行注入的

@Controller
public class HelloController {
    @Autowired
    @Resource(name="user1")
    public User user;
    public void print(){
        user.print();
    }
}

4)@Autowired 的装配顺序

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

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

相关文章

【前端基础】Day 2 CSS层叠样式表

目录 1.CSS简历 2.CSS 基础选择器 2.1标签选择器 2.2类选择器 2.3 id选择器 2.4通配符选择器 2.5总结 3.CSS字体属性 字体属性总结 4.CSS文本属性 4.1颜色 4.2对齐文本 4.3装饰文本 4.4文本缩进 4.5行间距 4.6文本属性总结 5.CSS的引入方式 5.1内部样式表 …

计算机毕业设计SpringBoot+Vue.js汽车资讯网站(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

nuxt常用组件库html-validator、@nuxtjs/i18n、@nuxt/image、@unocss/nuxt使用解析

html-validator 主要用于自动验证nuxt服务器呈现的HTML(SSR和SSG),以检测可能导致水合错误的HTML常见问题,有助于减少水合错误,检测常见的可访问性错误。 安装 npx nuxilatest module add html-validator配置 若自动更新nuxt.config.ts配置文…

Leetcode-最大矩形(单调栈)

一、题目描述 给定一个仅包含 0 和 1 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。 输入:matrix [["1","0","1","0","0"],["1","0&…

Vue核心知识:动态路由实现完整方案

在Vue中实现动态路由,并结合后端接口和数据库表设计,是一个复杂的项目,需要多个技术栈和步骤的配合。以下将详细描述整个实现过程,包括数据库设计、后端接口设计、前端路由配置以及如何实现动态路由的功能。 目录 一、需求分析二…

【Docker】使用Docker搭建-MySQL数据库服务

零、更换Docker镜像源 因为国内现在封锁了Docker默认拉取镜像的站点(DockerHub),而且国内大部分Docker镜像站已全部下线,导致现在很多朋友在拉取镜像的时候会出现无法拉取的现象,这时候就需要进行更换Docker镜像源。 可…

DHCP配置和地址

DHCP:动态主机配置协议 DHCP系统组成 DHCP报文结构 DHCP报文类型 DHCP工作流程 DHCP租期更新 DHCP重绑定 自动保留IP 租期设置建议 IP地址释放 DHCP地址池 DHCP配置 DHCP接口地址池配置 DHCP全局地址池配置

基于trl复现DeepSeek-R1的GRPO训练过程

1. 引入 huggingface开发了强化学习训练Transformer的库trl(参考3),借助这个trl,可以用来做GRPO的强化学习训练。魔搭ModelScope社区的文章(参考2)给出了基于Qwen基座模型Qwen2.5-0.5B-Instruct&#xff0…

常用的 pip 命令

pip 是 Python 的包管理工具,可用于安装、卸载、更新和管理 Python 包。以下是一些常用的 pip 命令: 1. 安装包 安装最新版本的包 pip install package_namepackage_name 是你要安装的 Python 包的名称,例如 pip install requests 可以安装…

基于C#的CANoe CLR Adapter开发指南

一、引言 CANoe 是一款广泛应用于汽车电子开发和测试的工具,它支持多种编程接口,方便开发者进行自定义扩展。CANoe CLR Adapter 允许我们使用 C# 语言与 CANoe 进行交互,充分利用 C# 的强大功能和丰富的类库。本文将详细介绍如何基于 C# 进行…

eMMC安全简介

1. 引言 术语“信息安全”涵盖多种不同的设计特性。一般而言, 信息安全是指通过实践防止信息遭受未经授权的访问、使用、披露、中断、篡改、检查、记录或销毁。 信息安全的三大核心目标为 机密性(Confidentiality)、完整性(Integr…

从零开始用react + tailwindcss + express + mongodb实现一个聊天程序(六) 导航栏 和 个人信息设置

1.导航栏(navbar) 在components下面 创建NavBar.jsx import { MessageSquare,Settings,User,LogOut} from "lucide-react" import {Link} from "react-router-dom" import { useAuthStore } from "../store/useAuthStore&qu…

数据库MySQL,在终端输入后,提示不是内部命令等

【解决问题】mysql提示不是内部或外部命令,也不是可运行的程序 一般这种问题是因为没有在系统变量里面添加MySQL的可执行路径 以下是添加可执行路径的方法: 第一步:winR输入services.msc 然后找到MySQL,右击属性并复制MySQL的可执…

C语言生成二维码

1. 效果 2. 需要的代码&#xff08;QRCode&#xff09; qrcode.cqrcode.h 代码 3. 代码 #include <stdio.h> #include "qrcode.h"int main() {//拓展编码SetConsoleOutputCP(437);QRCode qrcode;uint8_t qrcodeBytes[qrcode_getBufferSize(3)];qrcode_initT…

[Web 安全] PHP 反序列化漏洞 —— POP 链构造思路

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01&#xff1a;什么是 POP 链&#xff1f; POP 链&#xff08;Payload On Purpose Chain&#xff09;是一种利用 PHP 中的魔法方法进行多次跳转以获取敏感数据的技术。它通常出现在 CTF…

深度探索推理新境界:DeepSeek-R1如何用“自学”让AI更聪明?

今天我们要聊从1月初火到现在的AI模型——DeepSeek-R1。它就像一个“自学成材的学霸”&#xff0c;不用老师手把手教&#xff0c;就能在数学、编程、逻辑推理等领域大显身手&#xff01;仔细阅读了深度求索发表的R1论文&#xff0c;发现它不仅揭秘了它的成长秘籍&#xff0c;还…

2025春新生培训数据结构(树,图)

教学目标&#xff1a; 1&#xff0c;清楚什么是树和图&#xff0c;了解基本概念&#xff0c;并且理解其应用场景 2&#xff0c;掌握一种建图&#xff08;树&#xff09;方法 3&#xff0c;掌握图的dfs和树的前中后序遍历 例题与习题 2025NENU新生培训&#xff08;树&#…

keil主题(vscode风格)

#修改global.prop文件&#xff0c;重新打开keil即可 # Keil uVision Global Properties File # This file is used to customize the appearance of the editor# Editor Font editor.font.nameConsolas editor.font.size10 editor.font.style0# Editor Colors editor.backgro…

使用Hydra进行AI项目的动态配置管理

引言:机器学习中的超参数调优挑战 在机器学习领域,超参数调优是决定模型性能的关键环节。不同的模型架构,如神经网络中的层数、节点数,决策树中的最大深度、最小样本分割数等;以及各种训练相关的超参数,像学习率、优化器类型、批量大小等,其取值的选择对最终模型的效果…

深入了解 K-Means 聚类算法:原理与应用

引言 在数据科学和机器学习的世界中&#xff0c;聚类是一项非常重要的技术&#xff0c;它帮助我们根据数据的相似性将数据划分为不同的组或簇。聚类算法在许多领域中得到了广泛的应用&#xff0c;如图像处理、市场细分、基因研究等。K-Means 聚类算法作为最常见的无监督学习算…