Spring IoCDI

文章目录

  • 一、Spring、Spring boot、Spring MVC之间的区别
  • 1. Spring 是什么
  • 2. 区别概述

一、Spring、Spring boot、Spring MVC之间的区别

1. Spring 是什么

Spring 是包含了众多工具方法的 IoC 容器

(1)容器

容器是用来容纳某种物品的基本装置,比如List/Map就是数据存储容器,Tomcat就是Web容器

(2)loC

1. 概述

loC:Inversion if Control(控制反转),也就是说Spring 是一个“控制反转”的容器,是 Spring 的核心思想

eg. 在类上添加@RestController 和 @Controller 注解,就是把这个对象交给 Spring管理,Spring 框架启动时就会加载该类,即实现了把对象交给Spring管理

在这里插入图片描述
这部分代码就是loC容器做的事

IoC容器的优点
资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。

  1. 资源集中管理: IoC容器会帮我们管理一些资源(对象等),我们需要使用时, 只需要从IoC容器中去取就可以了
  2. 我们在创建实例的时候不需要了解其中的细节, 降低了使用资源双方的依赖程度, 也就是耦合度

代码方面理解:把材料外包出去,不自己制造

2. 使用

【1】Bean的存储

Spring 是一个loC容器,而作为容器,那【存】和【取】的功能就是最基本的。
Spring 容器 管理的主要是对象,这些对象, 我们称之为"Bean"。我们把这些对象交由Spring管理, 由Spring来负责对象的创建和销毁. 我们程序只需要告诉Spring,哪些需要存,以及如何从Spring中取出对象

对于 Spring 框架而言,共有两类注解可以将某个对象交给loC容器管理

  1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration
  2. 方法注解:@Bean

Bean 的 名称:Spring bean 是Spring框架在运行时管理的对象,Spring 会给管理的对象起一个名字,而根据这个名称(BeanId)就可以获取到对应的对象

Bean的命名约定:程序开发人员不需要为bean指定名称(BeanId), 如果没有显式的提供名称(BeanId),Spring容器将为该bean生成唯⼀的名称

命名约定使用Java标准约定作为实例字段名. 也就是说,bean名称以小写字母开头,然后使用驼峰式大小写

  • 类名: UserController, Bean的名称为:userController
  • 类名: AccountManager, Bean的名称为:accountManager

也有⼀些特殊情况, 当有多个字符并且第⼀个和第⼆个字符都是大写时, 将保留原始的大小写

  • 类名: UController, Bean的名称为:UController
  • 类名: AManager, Bean的名称为:AManager

@Controller(控制器存储)

@Controller
public class UserController {
    public void sayHi(){
        System.out.println("这是UserController");
    }
}

@SpringBootApplication
public class demo {

    public static void main(String[] args) {
        //获取Spring上下文对象
        ApplicationContext context = SpringApplication.run(demo.class, args);
        //从上下文中获取对象,下面是三种不同的获取方式
        //根据类的类型获取
        UserController userController1 = context.getBean(UserController.class);
        //根据名称获取,需要强转
        UserController userController2 = (UserController) context.getBean("userController");
        //根据名称和类型获取,不需要强转
        UserController userController3 = context.getBean("userController", UserController.class);

        System.out.println(userController1);
        System.out.println(userController2);
        System.out.println(userController3);

    }

}

在这里插入图片描述

获取bean对象, 是父类BeanFactory提供的功能

  • ApplicationContext VS BeanFactory(常见面试题)
    • 继承关系和功能方面来说:Spring 容器有两个顶级的接口:BeanFactory 和 ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能力,而ApplicationContext 属于 BeanFactory 的子类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性,还添加了对国际化支持、资源访问支持、以及事件传播等方面的支持。
    • 从性能方面来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,而
      BeanFactory 是需要那个才去加载那个,因此更加轻量。(空间换时间)

@Service(服务存储)

@Service
public class UserService {
    public void sayHi(){
        System.out.println("这是UserService");
    }
}


@SpringBootApplication
public class demo {

    public static void main(String[] args) {
        //获取Spring上下文对象
        ApplicationContext context = SpringApplication.run(demo.class, args);
        UserService service = context.getBean(UserService.class);
        service.sayHi();

    }

}

@Repository(仓库存储)、@Configuration(配置存储)、@Component(组件存储)的操作与上述都类似,只需要更改注解

@SpringBootApplication
public class SpringIocDemoApplication {
	public static void main(String[] args) {
		//获取Spring上下⽂对象
		ApplicationContext context = SpringApplication.run(SpringIocDemoApplicatio
		//从Spring上下⽂中获取对象
		UserConfiguration userConfiguration = context.getBean(UserConfiguration.cl
		//使⽤对象
		userConfiguration.sayHi();
	}
}

为什么需要这么多的注解???

让程序员看到类注解之后,就能直接了解当前类的用途

  • @Controller:控制层, 接收请求, 对请求进行处理, 并进行响应
  • @Servie:业务逻辑层, 处理具体的业务逻辑
  • @Repository:数据访问层,也称为持久层. 负责数据访问操作
  • @Configuration:配置层. 处理项目中的⼀些配置信息

应用分层的调用逻辑
在这里插入图片描述
方法注解 @Bean

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

  1. 使用外部包里的类, 没办法添加类注解
  2. ⼀个类, 需要多个对象,比如多个数据源
    这种场景, 我们就需要使用方法注解 @Bean,@Bean 注解的bean, bean的名称就是它的方法名

使用时的注意点

  • 在 Spring 框架的设计中,方法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中
  • bean想要生效,还需要被Spring扫描
    • 通过 @ComponentScan 来配置扫描路径
    • 有时候 @ComponentScan 注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication 中了。默认扫描的范围是SpringBoot启动类所在包及其子包
@Configuration
public class BeanConfig {
    @Bean
    public UserInfo userInfo(){
        UserInfo user = new UserInfo();
        user.setName("zhangsan");
        user.setAge(18);
        return user;
    }
}

定义多个对象

@Configuration
public class BeanConfig {
    @Bean
    public UserInfo userInfo1(){
        UserInfo user = new UserInfo();
        user.setName("zhangsan");
        user.setAge(18);
        return user;
    }

    @Bean
    public UserInfo userInfo2(){
        UserInfo user = new UserInfo();
        user.setName("lisi");
        user.setAge(22);
        return user;
    }
}



@SpringBootApplication
public class St20231205Application {

    public static void main(String[] args) {
    	//根据名称获取Bean对象
        UserInfo userInfo1 = (UserInfo) context.getBean("userInfo1");
        UserInfo userInfo2 = (UserInfo) context.getBean("userInfo2");

        System.out.println(userInfo1);
        System.out.println(userInfo2);
    }

}

重命名Bean

@Bean(name = {"u1","user1"})
public User user1(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
}


@SpringBootApplication
public class SpringIocDemoApplication {
    public static void main(String[] args) {
        //获取Spring上下⽂对象
        ApplicationContext context = SpringApplication.run(SpringIocDemoApplicatio
                //从Spring上下⽂中获取对象
                User u1 = (User) context.getBean("u1");
        //使⽤对象
        System.out.println(u1);
    }
}

name={} 可以省略,如下代码所示,如:
@Bean({“u1”,“user1”})
public User user1(){
          User user = new User();
          user.setName(“zhangsan”);
          user.setAge(18);
          return user;
}

只有⼀个名称时, {}也可以省略, 如:
@Bean(“u1”)
public User user1(){
          User user = new User();
          user.setName(“zhangsan”);
          user.setAge(18);
          return user;
}

(3)DI

1. 概述

DI: Dependency Injection(依赖注入),即容器在运行期间, 动态的为应用程序提供运行时所依赖的资源,如果程序运行时需要某个资源(对象),此时容器就为其提供这个资源。

所以,DI 和 loC是从不同的角度去描述同一件事情,即都是通过引入loC容器,利用依赖关系注入的方式,实现对象之间的解耦。loC是一种思想,而DI是loC的一种具体实现

依赖注入是⼀个过程,是指IoC容器在创建Bean时, 去提供运行时所依赖的资源,而资源指的就是对象

2. 使用

关于依赖注入,Spring也给我们提供了三种方式:

  1. 属性注入(Field Injection)
  2. 构造方法注入(Constructor Injection)
  3. Setter 注入(Setter Injection)

(1)属性注入

属性注入是使用 @Autowired 实现的,将 Service 类注入到 Controller 类中

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    public void sayHi() {
        System.out.println("Hi,UserController");
        userService.sayHi();
    }

}

@Service
public class UserService {
    public void sayHi() {
        System.out.println("Hi,UserService");
    }
}


@SpringBootApplication
public class demo {

    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(demo.class, args);
        UserController userController = (UserController)context.getBean("userController");
        userController.sayHi();
    }

}

(2)构造方法注入

@Controller
public class UserController2 {
    private UserService userService;

    @Autowired
    public UserController2(UserService userService){
        this.userService = userService;
    }

    public void sayHi() {
        System.out.println("Hi,UserController2");
        userService.sayHi();
    }
}

(3)Setter注入

@Controller
public class UserController3 {
    //注⼊⽅法3: Setter⽅法注⼊
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void sayHi(){
        System.out.println("hi,UserController3...");
        userService.sayHi();
    }
}

(4)三种注入优缺点分析

  • 属性注入
    • 优点: 简洁,使用方便
    • 缺点:
      • 只能用于 IoC 容器,如果是非 IoC 容器不可用,并且只有在使用的时候才会出现 NPE(空指针异常)
      • 不能注入⼀个Final修饰的属性
  • 构造函数注⼊(Spring 4.X推荐)
    • 优点:
      • 可以注入final修饰的属性
      • 注入的对象不会被修改
      • 依赖对象在使用前⼀定会被完全初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行的方法
      • 通用性好, 构造方法是JDK支持的, 所以更换任何框架,他都是适用的
    • 缺点:
      • 注入多个对象时, 代码会比较繁琐
  • Setter注入(Spring 3.X推荐)
    • 优点: 方便在类实例之后, 重新对该对象进行配置或者注入
    • 缺点:
      • 不能注入⼀个Final修饰的属性
      • 注入对象可能会被改变, 因为setter方法可能会被多次调用, 就有被修改的风险

(4)@Autowired存在问题

当同⼀类型存在多个bean时,使用@Autowired会存在问题。

解决方法

  1. @Primary:确定默认的实现
@Component
public class BeanConfig {
 	@Primary //指定该bean为默认bean的实现
	@Bean("u1")
 	public User user1(){
 		User user = new User();
 		user.setName("zhangsan");
 		user.setAge(18);
 		return user;
 	}
 	
 	@Bean
 	public User user2() {
 		User user = new User();
 		user.setName("lisi");
 		user.setAge(19);
 		return user;
 	}
}
  1. @Qualifier:指定当前要注入的bean对象。@Qualifier注解不能单独使用,必须配合@Autowired使用

```java
@Controller
public class UserController {
 	@Qualifier("user2") //指定bean名称
	@Autowired
 	private User user;
 	public void sayHi(){
 		System.out.println("hi,UserController...");
 		System.out.println(user);
 	}
}
  1. @Resource:按照bean的名称进行注入。通过name属性指定要注⼊的bean的名称
@Controller
public class UserController {
 	@Resource(name = "user2")
 	private User user;
 	public void sayHi(){
 		System.out.println("hi,UserController...");
 		System.out.println(user);
 	}
}

@Autowird 与 @Resource的区别

  • @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
  • @Autowired 默认是按照类型注入,而@Resource是按照名称注⼊. 相比于 @Autowired 来说,@Resource 支持更多的参数设置,例如 name 设置,根据名称获取 Bean

2. 区别概述

Spring:简单来说,Spring 是⼀个开发应用框架,什么样的框架呢,有这么几个标签:轻量级、⼀站式、模块化,其目的是用于简化企业级应用程序开发

Spring的主要功能: 管理对象,以及对象之间的依赖关系, ⾯向切⾯编程, 数据库事务管理, 数据访问,web框架支持等
但是Spring具备高度可开放性, 并不强制依赖Spring, 开发者可以自由选择Spring的部分或者全
部,Spring可以无缝继承第三方框架,比如数据访问框架(Hibernate 、JPA),web框架(如Struts、JSF)

Spring MVC:Spring MVC是Spring的⼀个子框架, Spring诞生之后,⼤家觉得很好用,于是按照MVC模式设计了⼀个 MVC框架(一些用Spring 解耦的组件), 主要用于开发WEB应用和网络接口,所以,Spring MVC 是⼀个Web框架

Spring MVC基于Spring进行开发的, 天生的与Spring框架集成. 可以让我们更简洁的进行Web层开发, 支持灵活的 URL 到页面控制器的映射, 提供了强大的约定大于配置的契约式编程支持, 非常容易与其他视图框架集成,如 Velocity、FreeMarker等

Spring Boot:Spring Boot是对Spring的⼀个封装, 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot 可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和⼀些底层的实现

Spring Boot 是个脚⼿架, 插拔式搭建项目, 可以快速的集成其他框架进来

Spring MVC和Spring Boot都属于Spring,Spring MVC 是基于Spring的⼀个MVC 框架,⽽Spring Boot 是基于Spring的⼀套快速开发整合包

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DevEco Studio无法识别本地模拟器设备的解决方法

遇到了一个问题,之前测试无误的本地模拟器,运行后设备栏中无法识别了。 此时保持模拟器处于开启状态,关闭DevEco Studio窗口重新启动后,发现重新识别设备了。

vue项目中 CDN 是vue本身的依赖可以按需加载还是项目中所有的第三方库都可以按需加载?

这是我看到CDN简介时产生的问题 相信很多小伙伴会有 和我一样的疑问 在这里 我也统一回答一下 CDN(内容分发网络)是一种通过将数据分发到全球各个节点,以提供快速、可靠的内容传输的技术。在Vue项目中,CDN可以用于按需加载Vue本…

c语言中的static静态(1)static修饰局部变量

#include<stdio.h> void test() {static int i 1;i;printf("%d ", i); } int main() {int j 0;while (j < 5){test();j j 1;}return 0; } 在上面的代码中&#xff0c;static修饰局部变量。 当用static定义一个局部变量后&#xff0c;这时局部变量就是…

【TB作品】51单片机,具有报时报温功能的电子钟

2.具有报时报温功能的电子钟 一、功能要求: 1.显示室温。 2.具有实时时间显示。 3.具有实时年月日显示和校对功能。 4.具有整点语音播报时间和温度功能。 5.定闹功能,闹钟音乐可选。 6.操作简单、界面友好。 二、设计建议: 1.单片机自选(C51、STM32或其他单片机)。 2.时钟日历芯…

L1-047:装睡

题目描述 你永远叫不醒一个装睡的人 —— 但是通过分析一个人的呼吸频率和脉搏&#xff0c;你可以发现谁在装睡&#xff01;医生告诉我们&#xff0c;正常人睡眠时的呼吸频率是每分钟15-20次&#xff0c;脉搏是每分钟50-70次。下面给定一系列人的呼吸频率与脉搏&#xff0c;请你…

智能优化算法应用:基于松鼠算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于松鼠算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于松鼠算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.松鼠算法4.实验参数设定5.算法结果6.参考文献7.MA…

qt实现基本文件操作

先通过ui界面实现基本框架 接下来就要实现每个按键的功能了 我们先来实现新建的的功能&#xff0c;我们右键新建键&#xff0c;可以发现没有转到槽的功能&#xff0c;因此我们要自己写connect来建立关系。 private slots:void newActionSlot(); 在.h文件中加上槽函数。 conne…

PMP项目管理 - 风险管理

系列文章目录 PMP项目管理 - 质量管理 PMP项目管理 - 采购管理 PMP项目管理 - 资源管理 PMP项目管理 - 风险管理 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream weaving wings, let the dream fly in…

常见Appium相关问题及解决方案

问题1&#xff1a;adb检测不到设备 解决&#xff1a; 1.检查手机驱动是否安装&#xff08;win10系统不需要&#xff09;&#xff0c;去官网下载手机驱动或者电脑下载手机助手来辅助安装手机驱动&#xff0c;安装完成后卸载手机助手&#xff08;防止接入手机时抢adb端口造成干…

【教3妹学编程-算法题】找到 Alice 和 Bob 可以相遇的建筑

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 3妹&#xff1a;好冷啊&#xff0c; 冻得瑟瑟发抖啦 2…

SpringBoot 源码解析2:启动流程1

SpringBoot 源码解析2&#xff1a;启动流程1 1.启动方式2.SpringBootApplication3.SpringApplication3.1 构造器SpringApplication3.2 SpringApplication#run 3.3 SpringApplication#run 中关键方法3.1 SpringApplication#prepareEnvironment3.2 SpringApplication#prepareCont…

CSS篇之圆角梯形

附上一篇文章&#xff1a;梯形tab按钮-基于clip-path path函数实现 - JSRUN.NET 他这个区别在于&#xff0c;收尾两侧都是直角的&#xff0c;如图 下面这个是圆角&#xff1a; 思路&#xff1a; 代码如下&#xff1a; <template><div class"wrap"><…

什么是Vue?

什么是Vue 什么是Vue&#xff1f;Vue 快速入门常用指令生命周期生命周期介绍生命周期 函数调用情况 什么是Vue&#xff1f; Vue 快速入门 常用指令 生命周期 生命周期介绍 生命周期 函数调用情况

Lit官方入门示例

陈拓 2023/12/17-2023/12/17 1. 简介 在《用Vite构建Lit项目》 https://blog.csdn.net/chentuo2000/article/details/134831884?spm1001.2014.3001.5501 一文中我们介绍了怎样用Vite构建Lit项目。 本文我们介绍不依赖Vite的Lit入门示例。 我的开发环境还是和上文相同。 …

C语言—每日选择题—Day50

一天一天的更新&#xff0c;也是达到50天了&#xff0c;精选的题有250道&#xff0c;博主累计做了不下500道选择题&#xff0c;最喜欢的题型就是指针和数组之间的计算呀&#xff0c;不知道关注我的小伙伴是不是一直在坚持呢&#xff1f;文末有投票&#xff0c;大家可以投票让博…

HarmonyOS应用开发者高级认证考试满分答案(100分)【全网最全-不断更新】【鸿蒙专栏-28】

系列文章&#xff1a; HarmonyOS应用开发者基础认证满分答案&#xff08;100分&#xff09; HarmonyOS应用开发者基础认证【闯关习题 满分答案】 HarmonyOS应用开发者高级认证满分答案&#xff08;100分&#xff09; HarmonyOS云开发基础认证满分答案&#xff08;100分&#xf…

【MyBatis-Plus】常用的插件介绍(乐观锁、逻辑删除、分页)

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于MyBatis-Plus的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.为什么要使用MyBatis-Plus中的插…

1. MongoDB快速实战与基本原理

1.MongoDB介绍 1.1 什么是MongoDB MongoDB是一个文档数据库&#xff08;以JSON 为数据模型&#xff09;&#xff0c;由C语言编写&#xff0c;旨在为WEB应用提供可扩展的高性能数据存储解决方案。 文档来自于“JSON Document”&#xff0c;并非我们一般理解的 PDF&#xff0c;…

【Qt图书管理系统】4.系统设计与详细设计

文章目录 核心流程图软件架构设计流程图软件开发类图及功能点 核心流程图 用户登录图书查询图书借阅图书归还账户管理 软件架构设计 流程图 软件开发类图及功能点 Dlg_Login 登录界面 Cell_Main 主窗体 Cell_MyBook 我的书籍 Cell_BookMgr 书籍管理 Cell_RecoredMgr 借阅记录…

cmd发生系统错误 5。的解决方法

我敲[net start mysql]命令时遇到如图报错&#xff0c;下面介绍解决方法&#xff0c;非常简单。 我们只需要更改打开cmd的方式&#xff0c;我之前直接敲WinR组合键&#xff0c;输入cmd命令打开的&#xff0c;不要这样做。我们输入“命令提示符”&#xff0c;然后选择“以管理员…