【Spring】 IoCDI

 回顾

企业命名规范

大驼峰:BookDao(首字母都大写)

类名

小驼峰:bookDao(第一个字母小写)

方法名

蛇形:book_dao(小写+下划线_)

数据库

串形:book-dao(小写+连字符-)

项目文件夹

各种注解

学习Spring MVC, 其实就是学习各种Web开发需要⽤的到注解

a. @RequestMapping: 路由映射

b. @RequestParam: 后端参数重命名

c. @RequestBody: 接收JSON类型的参数

d. @PathVariable: 接收路径参数

e. @RequestPart: 上传⽂件

f. @ResponseBody: 返回数据

g. @CookieValue: 从Cookie中获取值

h. @SessionAttribute: 从Session中获取值

i. @RequestHeader: 从Header中获取值

 j. @Controller: 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理. 默认返回 视图.

k. @RestController: @ResponseBody + @Controller 返回数据

好用的工具插件

Java EE学习阶段会涉及较多⼯具, 插件的学习, 来帮助我们提⾼开发效率. ⽐如Postman, lombok, EditStarter, 后⾯还会继续学习其他的⼯具或插件. 

一.Spring

Spring两大核心思想

1.IoC

2.AOP

1.IoC控制反转

Inversion of Control 控制反转,Spring是一个控制反转的容器.(spring拥有了创建对象的控制权)

举一个例子来理解什么是控制反转?

我们要造一辆汽车,汽车依赖车身,车身依赖底盘,底盘依赖轮子.

由于层层的依赖关系,程序的耦合度非常高,此时如果我们想改变位于底层的轮胎的大小,或者增加轮胎的属性,整个调用链上的所有代码都需要修改.这当然是是一个问题.

如果我们转变思路:先根据汽车的样子设计车身,再根据车身设计底盘,根据底盘设计轮子. 这个时候,他们的依赖关系就完全倒置了: 轮子依赖底盘,底盘依赖车身,车身依赖汽车.

实现:将所需要的依赖从原来创建下级类的方式改为传递/注入的方式,此时我们不需要关注下级类的属性变化,传递过来的是什么,我们就接受什么,此类本身并不需要修改代码.这也完成了程序的解耦!

IoC方式和传统方式的对比

传统开发对象的创建顺序: Car  -  FrameWork -  Bottom  -  Tire

改进之后的创建对象顺序:Tire  -  Bottom  -  Framework  -  Car

改进之后的控制权发生了反转,不再是使用方对象创建并控制依赖对象了,而是把依赖对象注入到当前对象中,依赖对象的控制权不再由当前类控制.

这也就是IoC的实现思想.


IoC容器的优点

资源不再由使用双方管理,而是由第三方管理

1.资源集中管理:IoC容器会帮我们管理一些资源对象,需要时,去容器中去取就可以了

2.解耦合:降低了使用资源双方的依赖程度,创建实例的时候不需要了解其中的细节

总结:Spring是一个包含众多工具的IoC容器,来帮助我们做资源管理.

IoC是一种思想,DI是IoC的一种实现方法.

2.DI依赖注入

Dependency Injection依赖注入

容器在运行期间,动态地为应用程序提供运行时所依赖的资源.

上述代码中就是通过构造函数的方式,把依赖对象注入到使用的对象中.

二.IoC 和 DI 的使用

Spring作为一个IoC容器,它具备两个最基础的功能,那就是存和取;

存和取的其实就是spring容器帮管我们管理的对象,我们把他们称之为Bean.

这些对象交由Spring管理,由Spring来负责对象的创建和销毁.

我们要做的分两步:

1.告诉Spring,哪些需要存

添加@Component注解(例)

2.知道如何从Spring取出对象

添加注解@Autowired

比如:

原本在UserController类中要使用UserDao对象,就需要new出UserDao对象,但是现在我们也可以将UserDao交给Spring管理了, 具体的实现只需要两步 : 

1.告诉Spring帮我们管理UserDao 

在类上面添加@Component注解

2.从Spring中获取UserDao对象

在对象声明时添加@Autowired注解

Bean的存储

上述IoC容器创建和管理对象的过程也就是bean的存储.

前面我们使用的是@Component注解来把对象交给IoC容器管理,而Spring框架为了更好服务web应用程序,提供了更更富的注解.

1.类注解(五大注解)

@Controller

控制层存储

@Service

服务存储

@Repository

仓库存储

@Component

组件存储

@Configuration

配置存储

1.1@Controller

使用@Controller存储bean:
 

从Spring上下文中获取bean对象的三种方式:

先获取到Spring上下文,再调用getBean方法.

  • getBean(Class)

  • getBean(String s)

这种要强转 .

特殊情形:如果类名前两位都是大写,那么不用变,直接使用原名

  • getBean(String , Class)

bean名的约定

类名: UserController, Bean的名称为: userController

类名: AccountManager, Bean的名称为: accountManager

类名: AccountService, Bean的名称为: accountService

特殊情况, 当有多个字符并且第⼀个和第⼆个字符都是⼤写时, 将保留原始的⼤⼩写.

⽐如

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

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

1.2@Service

1.3@Repository

1.4@Component

1.5@Configuration

上述四个注解和@Controller也是相同的使用方法.

为什么要这么多注解

其实注解和分层式呼应的.不同的注解对应不同的用途.

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

注解之间的关系

  • @Controller / @Service / @Repository / @Configuration 这四个注解的源码里都有一个@Component , 说明它们本身就是属于@Component的 " 子类 " ,@Component 是⼀个元注解,@Controller , @Service , @Repository 等. 这些注解被称为 @Component 的衍⽣注解.
  • @Controller , @Service 和 @Repository ⽤于更具体的⽤例(分别在控制层, 业务逻辑层, 持 久化层), 在开发过程中, 如果你要在业务逻辑层使⽤ @Component 或@Service,显然@Service是更 好的选择.
  • 只有@controller注解才可以被其他类访问到,这是controller的特殊功能.

ApplicationContext  和 BeanFactory

BeanFactory

获取bean对象其实是父类BeanFactory提供的功能.

  • 它们都是Spring容器的的顶级接口,其实BeanFactory提供了基础的访问容器的能力,ApplicationContext属于BeanFactory的子类,继承了BeanFactory的所有功能,并且还拥有独立的特性,添加了国际化支持/资源访问支持/时间传播

  • 性能:applicationContext是一次性加载并初始化所有Bean对象,而BeanFactory是懒加载,需要用到才会去加载,因此更轻量.

2.方法注解@bean

五大注解只能加载类上,并且只能加在自己的代码上

若想获取一个类的多个bean时,不能使用类型来获取对象. 否则会取到同一个对象.

2.1获取第三方类

由于五大注解只能加在自己写的类上,对于一些第三方的包,我们只能通过方法注解来获取第三方类

假如这是一个第三方类:

  • 方法注解必须搭配五大注解使用!

  • 一个类包含多个bean,只能使用bean名称获取

2.2bean传参

Bean会根据名称匹配. 但是如果对应类型的对象只有一个时,就不会看名称,而是直接赋值 .

(比如只有一个String类型的bean,此时参数就是一个String类型,那么就会直接用这个唯一的String类型的bean,而不会看名称匹配)


springBoot特点有一个特点是约定大于配置

体现:扫描路径

默认的扫描路径是启动类所在目录以及子目录.

另外,@ComponentScan("") 可以指定扫描路径.

如果没有指定,使用默认的扫描路径.

三.DI详解

依赖注入/属性装配

1.属性注入@Autowired

属性注入以类型进行匹配,与注入的属性名称无关

注意:无法注入final修饰的属性.

@Autowired的问题:如果一个类型存在多个对象,优先名称匹配,如果名称都匹配不上,那就会报错.

解决方式:

1.属性名和需要使用的对象名保持一致.(使用名称匹配)

2.使用@Primary注解表示默认的bean

3.使用@Qualifier来指定bean

4.使用@Resource来指定bean

@Autowired和@Resouce的区别

  • @Autowired是spring框架的注解,而@Resource是JDK提供的注解.
  • @Autowried是默认是按照类型注入,如果类型一样,优先按照名称匹配,而@Resource是按照名称注入,它可以设置name属性来获取bean

2.构造方法注入

如果只有一个构造函数,@Autowired可以省略

如果存在多个构造方法,需要加@Autowired注明使用哪个构造方法

3.Setter方法注入

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

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

相关文章

(一)C语言之入门:使用Visual Studio Community 2022运行hello world

使用Visual Studio Community 2022运行c语言的hello world 一、下载安装Visual Studio Community 2022 与 新建项目二、编写c helloworld三、编译、链接、运行 c helloworld1. 问题记录:无法打开源文件"stdio.h"2. 问题记录:调试和执行按钮是灰…

Leetcode算法系列| 1. 两数之和(四种解法)

目录 1.题目2.题解解法一:暴力枚举解法二:哈希表解法解法三:双指针(有序状态)解法四:二分查找(有序状态) 1.题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数…

前端 vue 面试题(二)

文章目录 如何让vue页面重新渲染组件间通信vue为什么要mutation、 action操作插槽、具名插槽、作用域插槽vue编译使用的是什么库?vue怎么实现treeshakingwebpack实现treeshaking为什么只有es module 能支持 tree shaking mixin 的作用mixin的底层原理nexTick原理vue…

小辰的智慧树(差分+前缀和)

登录—专业IT笔试面试备考平台_牛客网 1.考虑总长度之和不能超过m,2考虑限制每棵树高度不能低于ci,如果用二分最短输能截到的高度,还要另外去判断,是否每棵树mid都能严格大于ci ,这样容易超时,换个角度&…

14 redis全量复制与部分复制

1、设置主服务器的地址和端口 首先是在从服务器设置需要同步的主服务器信息,包括机器IP, 端口。 主从复制的开启,完全是在从节点发起的。不需要我们在主节点做任何事情。 从节点开启主从复制,有3种方式 配置文件:在从服务器的配…

使用【画图】软件修改图片像素、比例和大小

打开电脑画图软件,点击开始 windows附件 画图 在画图软件里选择需要调整的照片,点击文件 打开 在弹出窗口中选择照片后点击打开 照片在画图软件中打开后,对照片进行调整。按图中顺序进行 确定后照片会根据设定的值自动调整 保存…

P6 C++控制流语句(continue, break, return)

前言 今天我们讲的是控制流语句,本期内容是上期课程的延续。 控制流语句一般与循环语句一起工作,它们让我们可以更好的控制这些循环的实际运行。 我们有三个主要的控制流语句可以使用,continue 、break 和 return,它们有不同的…

CCFCSP试题编号:201803-2试题名称:碰撞的小球

一、题目描述 二、思路 1.首先妾身分析这个题目,想要解题,得得解决2个问题。 1)判断小球到达端点或碰撞然后改变方向; 2)每时刻都要改变位置 两个问题都比较好解决,1)只要简单判断坐标&…

【Vue】核心特性(响应式)

响应式&#xff1a; 数据变化&#xff0c;视图自动更新 接下来使用一个例子来体现一下什么是响应式 案例一&#xff1a; 访问数据&#xff0c;视图自动更新 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><…

12个最佳WordPress投票插件

您是否正在为您的网站寻找WordPress投票插件&#xff1f; WordPress投票插件可让您轻松地在您的网站上进行民意调查&#xff0c;用户可以投票。这是在收集见解的同时建立用户参与度的有效策略。 在本文中&#xff0c;我们精心挑选了最好的WordPress投票插件&#xff0c;可帮助…

【C/PTA】函数专项练习(四)

本文结合PTA专项练习带领读者掌握函数&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 计算A[n]1/(1 A[n-1])6-2 递归实现顺序输出整数6-3 自然数的位数(递归版)6-4 分治法求解金块问题6-5 汉诺塔6-6 重复显示字符(递归版)…

代码随想录算法训练营第五十二天|300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;代码随想录B站账号 状态&#xff1a;看了视频题解和文章解析后做出来了 300.最长递增子序列 class Solution: # 2516 ms, faster than 64.96%def lengthOfLIS(self, nums: List[int]) -> int:n len(nums)dp [1] * n…

黑马点评-10实现用户点赞和点赞排行榜功能

用户点赞功能 如果用户只要点赞一次就对数据库中blog表中的liked字段的值加1就会导致一个用户无限点赞 PutMapping("/like/{id}") public Result likeBlog(PathVariable("id") Long id) {// 修改点赞数量,update tb_blog set liked liked 1 where id …

JavaScript编程基础 – 布尔值(Booleans)

JavaScript编程基础 – 布尔值(Booleans) Javascript Programming Essentials – Booleans 一个JavaScript布尔值包含两个值中的一个&#xff0c;即 true 或者 false。 本文简要介绍JavaScript布尔值的具体应用&#xff0c;以及可能作为对象的布尔值等。 1. 布尔值(Booleans)…

Py之PyPDF2:PyPDF2的简介、安装、使用方法之详细攻略

Py之PyPDF2&#xff1a;PyPDF2的简介、安装、使用方法之详细攻略 目录 PyPDF2的简介 PyPDF2的安装 PyPDF2的使用方法 1、基础用法 PyPDF2的简介 PyPDF2是一个免费的、开源的纯python PDF库&#xff0c;能够拆分、合并、裁剪和转换PDF文件的页面。它还可以为PDF文件添加自定…

springcloud超市管理系统源码

技术说明&#xff1a; jdk1.8&#xff0c;mysql5.7&#xff0c;idea&#xff0c;vscode springcloud springboot mybatis vue elementui mysql 功能介绍&#xff1a; 后台管理&#xff1a; 统计分析&#xff1a;查看用户&#xff0c;商品&#xff0c;销售数量&#xff1b;…

JavaWeb——感谢尚硅谷官方文档

JavaWeb——感谢尚硅谷官方文档 XML一、xml简介二、xml的语法1、文档申明2、xml注释3、xml元素4、xml属性5、xml语法规则 三、xml解析技术1、使用dom4j解析xml Tomcat一、JavaWeb的概念二、web资源的分类三、常见的web服务器四、Tomcat的使用1、安装2、Tomcat的目录介绍3 启动T…

数据结构-leetcode(设计循环队列)

1.学习内容&#xff1a; 今天 我们讲解一道能够很好的总结所学队列知识的题目---设计循环队列 622. 设计循环队列 - 力扣&#xff08;LeetCode&#xff09; 2.题目描述&#xff1a; 让我们设计一个队列 要求是循环的 这和我们的双向链表有些类似 让我们按要求设计出这些相对…

视频云存储EasyCVR平台国标接入获取通道设备未回复是什么原因?该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…

Python中的解析器argparse

import argparse## 构造解析器 argparse.ArgumentParser() parse argparse.ArgumentParser(description"caculateing the area of rectangle")## 添加参数 .add_argument() parse.add_argument("--length",typeint,default20,helpThe length of rectangle…