Spring IoC 容器的使用详解(最新整理)

2025-07-02 17:50

本文主要是介绍Spring IoC 容器的使用详解(最新整理),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《SpringIoC容器的使用详解(最新整理)》文章介绍了Spring框架中的应用分层思想与IoC容器原理,通过分层解耦业务逻辑、数据访问等模块,IoC容器利用@Component注解管理Bean...

1. 应用分层

应用分层是一种软件开发设计思想,它将应用程序分成 N 个层次,这 N 个层次分别负责各自的职责,多个层次之间协同提供完整的功能,根据项目的复杂度,可以分成三层,四层或更多层,MVC 就是把整体的程序分成了 Model(模型), View(视图), Controller(控制器)三个层次

Spring IoC 容器的使用详解(最新整理)

由于后端开发,不需要过多的关注前端,所以又有了一种分层架构:把整体架构分为表现层,业务逻辑层,数据层,又称为“三层架构”

  1. 表现层:用来展示数据结果和接收用户指令,是最接近用户的一层
  2. 业务逻辑层:负责处理业务逻辑,包含业务逻辑的具体实现
  3. 数据层:负责存储和管理与应用程序相关的数据

在 Spring 的实现中可以分为下面三个部分:

Spring IoC 容器的使用详解(最新整理)

Controller:控制层。接收前端发送的请求,对请求进行处理,并响应数据

Service:业务逻辑层。处理具体的业务逻辑

Dao:数据访问层,也被称为持久层。负责数据访问,操作(增删查改)

2. IoC 的介绍

IoC:也就是控制反转

Spring IoC 是一种设计模式,用于解耦对象之间的依赖关系,在之前创建的项目中对象通常会主动创建和管理自己所依赖的对象,例如,一个UserService类可能会在自己的内部使用new关键字来创建一个UserRepository对象用于数据访问,这样设计看似没有问题,但是可维护性却很低,当有很多类创建了各自的对象时,并且这些对象之间还有依赖关系,例如创建 Car ,Framework,Bottom,Tire 类,从左到右依次存在依赖关系,当其中有一个类的底层代码改变之后,调用链上的代码都需要修改

public class NewCarExample {
    public static void main(String[] args) {
        Car car = new Car(20);
        car.run();
    }
    //Car类
    static class Car {
        private Framework framework;
        public Car(int size) {
            framework = new Framework(size);
            System.out.println("Car init....");
        }
        public void run(){
            System.out.println("Car run...");
        }
    }
    //车身类
    static class Framework {
        private Bottom bottom;
        public Framework(int size) {
            bottom = new Bottom(size);
            System.out.println("Framework init...");
        }
    }
    //底盘类
    static class Bottom {
        private Tire tire;
        public Bottom(int size) {
            this.tire = new Tire(size);
            System.out.println("Bottom init...");
        }
    }
    //轮胎类
    static class Tire {
        // 尺⼨
        private int size;
        public Tire(inhttp://www.chinasem.cnt size){
            this.size = size;
            System.out.println("轮胎尺⼨:" + size);
        }
    }
}

Spring IoC 容器的使用详解(最新整理)

修改轮胎的构造方法之后,底盘也需要修改,当修改底盘之后,上层调用也需要修改

而在 IoC 模式下,对象的创建和管理这些控制权被反转了,不再由对象自身来控制,而是交给外部的容器(IoC 容器)来管理,下面演示一下使用 IoC 的思想来管理对象

public class IocCarExample {
    public static void main(String[] args) {
        Tire tire = new Tire(20);
        Bottom bottom = new Bottom(tire);
        Framework framework = new Framework(bottom);
        Car car = new Car(framework);
        car.run();
    }

通过这样的形式,各个组件的依赖关系就发生了反转,统一对对象进行管理,谁需要这个对象直接传过去一个对象,不需要他自己调用方法进行创建

Spring IoC 容器的使用详解(最新整理)

IoC 容器的工作就是把这些对象进行统一管理

Spring IoC 容器的使用详解(最新整理)

通过这种方式进行资源的统一管理,在创建实例时不需要了解其中的细节,降低了使用资源双方的依赖程度

3. IoC 容器的使用

3.1. bean 的存储

如果想要把一个对象交给 IoC 容器来管理,需要在类上添加一个 @Component 注解,此外还有其它的一些注解可以实现:

  1. 类注解:@Controller@Service@Repository@Component@Configuration.
  2. 方法注解:@Bean.
@Controller
public cl编程ass UserController {
    public void say(){
        System.out.println("UserController");
    }
}
@SpringBootApplication
public class SpringIoCApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(SpringIoCApplication.class, args);
        UserController bean = context.getBean(UserController.class);
        bean.say();
    }
}

ApplicationContext 可以理解为 Spring 的上下文,这个上下文就是指当前的运行环境和其他功能,也可以看作是一个容器,容器中存储了很多内容,这些内容是当前的运行环境

之后就可以通过拿到的 context 来获取 bean,关于获取 bean 有多种方式:

Object getBean(String var1) throws BeansException;

根据bean名称获取bean

T getBean(String var1, Class var2) throws BeansException;

根据bean名称和类型获取bean

T getBean(Class var1) throws BeansException;

根据类型获取bean

Object getBean(String var1, Object... var2) throws BeansException

按bean名称和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的bean

T getBean(Class var1, Object... var2) throws BeansException;

按bean类型和构造函数参数动态创建bean, 只适⽤于具有原型(prototype)作⽤域的 bean

根据类型获取 bean 的话,如果存在多个相同类型的 bean 那么就不能确定具体要获取的是哪个 bean ,同理,如果只是根据名称来获取 beanChina编程,如果重名的话也是不能正确获取到 bean 的,所以就有了第三种方式,同时根据类型和名称来获取 bean

上面这三种获取 bean 的方式是比较常用的

关于 IoC 中 bean 的名称转化规则:

如果是 UserController 会被转成 userController,如果是 UController 就还是 UController

UserController bean1 = (UserController) context.getBean("userController");
bean1.say();

由于是根据名称来获取 bean,所以获取到的 bean 不确定是什么类型,会返回一个 Object 类型,需要强转一下

同时指定类型和名称:

UserController bean2 = context.getBean(China编程"userController", UserController.class);
bean2.say();

Spring IoC 容器的使用详解(最新整理)

把上面获取的 bean ,打印一下,发现获取的实例的地址是一样的,由此可以知道,通过这种方式获取对象是基于单例模式实现的

接下来演示一下 @Service 注解:

@Service
public class UserService {
    public void say(){
        System.out.println("UserService");
    }
}
UserService service = context.getBean(UserService.class);
service.say();

然后发现和上面一样也是可以运行的,其它的几个类注解也是一样的

那么为什么实现的功能一样,还需要分这么多不同的注解,这个是和之前的应用分层是对应的,通过不同的类注解来了解当前类的用途

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

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

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

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

3.2. 方法注解@Bean

上面四个注解都是 @Component的衍生注解

类注解是添加到某个类上的,但是存在两个问题:

  1. 如果使用外部包里的类,没办法添加注解
  2. 同时,由于类注解默认创建的对象是单例对象,如果需要多个对象就需要调整

方法注解 @Bean就可以解决上述问题

例如,在一个外部包里有一个 UserInfo 类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo {
    private String name;
    private Integer age;
}

可以通过在获取对象的方法上加上@Bean

@Component
public class pythonUserInfoComponent {
    @Bean
    public UserInfo userInfo(){
        return new UserInfo("zhangsan",20);
    }
}

Spring IoC 容器的使用详解(最新整理)

如果说需要创建对个对象的话:

Spring IoC 容器的使用详解(最新整理)

这个问题就是在获取 bean 的时候发现了具有相同类型的 bean,可以直接通过获取 bean 的名称,这里的名称和方法注解下方法名是对应的

UserInfo bean = (UserInfo) context.getBean("userInfo");
System.out.println(bean);

上面的注解,无论是类注解还是方法注解,都可以实现重命名

Spring IoC 容器的使用详解(最新整理)

重命名之后就需要使用改之后的名字了

4. 扫描路径

Spring IoC 容器的使用详解(最新整理)

Spring IoC 容器的使用详解(最新整理)

如果说把启动类放到其他目录下再运行就会报错,是因为上面介绍的注解如果想要生效,是需要配置扫描路径的,默认的扫描范围是 Spring Boot 启动类所在的包和它的子包,可以通过@ComponentScan来配置扫描路径

Spring IoC 容器的使用详解(最新整理)

@ComponentScan源码中,是支持传入一个数组的,如果想要配置多个扫描路径可以直接传入一个数组

Spring IoC 容器的使用详解(最新整理)

@ComponentScan({"com.example.service","com.example.controller"})

到此这篇关于SpringIoC 容器的使用的文章就介绍到这了,更多相关SpringIoC 容器使用内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!

这篇关于Spring IoC 容器的使用详解(最新整理)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

MySQL 主从复制部署及验证(示例详解)

《MySQL主从复制部署及验证(示例详解)》本文介绍MySQL主从复制部署步骤及学校管理数据库创建脚本,包含表结构设计、示例数据插入和查询语句,用于验证主从同步功能,感兴趣的朋友一起看看吧... 目录mysql 主从复制部署指南部署步骤1.环境准备2. 主服务器配置3. 创建复制用户4. 获取主服务器状态5

SpringBoot中六种批量更新Mysql的方式效率对比分析

《SpringBoot中六种批量更新Mysql的方式效率对比分析》文章比较了MySQL大数据量批量更新的多种方法,指出REPLACEINTO和ONDUPLICATEKEY效率最高但存在数据风险,MyB... 目录效率比较测试结构数据库初始化测试数据批量修改方案第一种 for第二种 case when第三种

Java docx4j高效处理Word文档的实战指南

《Javadocx4j高效处理Word文档的实战指南》对于需要在Java应用程序中生成、修改或处理Word文档的开发者来说,docx4j是一个强大而专业的选择,下面我们就来看看docx4j的具体使用... 目录引言一、环境准备与基础配置1.1 Maven依赖配置1.2 初始化测试类二、增强版文档操作示例2.

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

Spring Boot中的路径变量示例详解

《SpringBoot中的路径变量示例详解》SpringBoot中PathVariable通过@PathVariable注解实现URL参数与方法参数绑定,支持多参数接收、类型转换、可选参数、默认值及... 目录一. 基本用法与参数映射1.路径定义2.参数绑定&nhttp://www.chinasem.cnbs

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

MySql基本查询之表的增删查改+聚合函数案例详解

《MySql基本查询之表的增删查改+聚合函数案例详解》本文详解SQL的CURD操作INSERT用于数据插入(单行/多行及冲突处理),SELECT实现数据检索(列选择、条件过滤、排序分页),UPDATE... 目录一、Create1.1 单行数据 + 全列插入1.2 多行数据 + 指定列插入1.3 插入否则更

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

MySQL 迁移至 Doris 最佳实践方案(最新整理)

《MySQL迁移至Doris最佳实践方案(最新整理)》本文将深入剖析三种经过实践验证的MySQL迁移至Doris的最佳方案,涵盖全量迁移、增量同步、混合迁移以及基于CDC(ChangeData... 目录一、China编程JDBC Catalog 联邦查询方案(适合跨库实时查询)1. 方案概述2. 环境要求3.

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完