Spring IoC DI

 博主主页: 码农派大星.

    数据结构专栏:Java数据结构

 数据库专栏:MySQL数据库

JavaEE专栏:JavaEE

关注博主带你了解更多数据结构知识

目录

1. 应用分层

1.1 如何分层:

1.2 MVC与三层架构区别联系

2. Spring

3.IoC & DI⼊⻔

3.1 什么是IoC?

3.2 DI 介绍 

4.IoC 使⽤

4.1 类注解区别

4.2 ⽅法注解@Bean

4.2.1⽅法注解要配合类注解使⽤

4.2.2 定义多个对象 

4.2.3 重命名Bean 

5. DI 依赖注入

5.1 属性注⼊

5.2 构造方法注入 

5.3 Setter 注⼊ 

5.4 三种注⼊优缺点 

属性注⼊

构造函数注⼊

 Setter注⼊

5.5 @Autowired存在问题

@Primary

@Qualifier

@Resource 

 @Resource 和@Autowired区别

6.Spring, Spring Boot和SpringMVC的关系以及区别 


1. 应用分层

应⽤分层是⼀种软件开发设计思想,它将应⽤程序分成N个层次,这N个层次分别负责各⾃的职责,多个层次之间协同提供完整的功能.根据项⽬的复杂度,把项⽬分成三层,四层或者更多层,之前为了让项⽬快速上线,我们通常是不考虑分层的.但是随着业务越来越复杂,⼤量的 代码混在⼀起,会出现逻辑不清晰、各模块相互依赖、代码扩展性差、改动⼀处就牵⼀发⽽动全⾝等问题.所以学习对项⽬进⾏分层对我们来说就是很有必要的了.

1.1 如何分层:

我们上一篇博客中学的Spring MVC中就把整体的系统分成了Model(模型),View(视图)Controller(控制器)三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构

对于我们后端开发来说,我们可以把整体架构分为表现层、业务逻辑层和数据层.这种分层⽅式也称之为"三层架构"

1. 表现层:就是展⽰数据结果和接受⽤⼾指令的,是最靠近⽤⼾的⼀层;(请求处理、响应数据:负责,接收⻚⾯的请求,给⻚⾯响应数据)

2. 业务逻辑层:负责处理业务逻辑, ⾥⾯有复杂业务的具体实现;(逻辑处理:负责业务逻辑处理的代码)

3. 数据层: 负责存储和管理与应⽤程序相关的数据(数据访问:负责业务数据的维护操作,包括增、删、改、查等操作.)

在Spring中我们把这三层分别分为:

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

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

Dao:数据访问层,也称为持久层。负责数据访问操作,包括数据的增、删、改、查

1.2 MVC与三层架构区别联系

MVC 是一种设计模式,用于分离应用程序的用户界面(UI)和业务逻辑,强调用户界面和业务逻辑的分离,使得开发者可以专注于单一方面的开发,而不必担心其他部分的实现细节

三层架构是一种软件架构模式,强调应用程序的不同功能层之间的分离,使得每一层都可以独立开发和测试

MVC 更侧重于用户界面的实现和业务逻辑的分离,而三层架构侧重于整个应用程序的分层和模块化

MVC模式强调数据和视图分离,将数据展⽰和数据处理分开,通过控制器对两者进⾏组合. 三层架构强调不同维度数据处理的⾼内聚和低耦合,将交互界⾯,业务处理和数据库操作的逻辑分开

联系:提高代码的可维护性和可扩展性,⼆者的⽬的是相同的,都是"解耦,分层,代码复⽤"

可测试性:通过分离不同的功能到不同的层或组件,两者都使得单元测试和集成测试变得更加容易。

可维护性:在 MVC 和三层架构中,代码的组织方式使得维护和更新变得更加简单

2. Spring

Spring就是包含了众多⼯具⽅法的IoC容器

3.IoC & DI⼊⻔

3.1 什么是IoC?

IoC 是Spring的核⼼思想,其实IoC我们在前⾯已经使⽤了,我们在前⾯讲到,在类上⾯添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时就会加载该类.把对象交 给Spring管理,就是IoC思想.

IoC: Inversion of Control (控制反转),也就是说Spring是⼀个"控制反转"的容器

什么是控制反转呢? 也就是控制权反转.什么的控制权发⽣了反转? 获得依赖对象的过程被反转了 也就是说,当需要某个对象时,传统开发模式中需要⾃⼰通过new创建对象,现在不需要再进⾏创 建, 把创建对象的任务交给容器, 程序中只需要依赖注⼊(DI)就可以了. 这个容器称为:IoC容器. Spring是⼀个IoC容器,所以有时Spring也称为Spring容器

控制反转是⼀种思想,在⽣活中也是处处体现. ⽐如⾃动驾驶, 传统驾驶⽅式,⻋辆的控制权由驾驶员行驶来控制,现在交给了驾驶自动化系统来控制,这也是控制反转思想在⽣活中的实现

IoC容器具备优点:

1. 资源集中管理: IoC容器会帮我们管理⼀些资源(对象等),我们需要使⽤时,只需要从IoC容器中去取 就可以了

2. 我们在创建实例的时候不需要了解其中的细节,降低了使⽤资源双⽅的依赖程度,也就是耦合度

3.2 DI 介绍 

DI就是依赖注入

它是实现 IoC一种设计模式。依赖注入的主要思想是将组件的依赖关系(即它所依赖的对象或资源)通过外部传递给它,而不是让组件自己创建或查找这些依赖

DI 是 IoC 的一种实现方式,它专注于解决对象之间的依赖关系。在 DI 中,一个对象(称为消费者)所依赖的另一个对象(称为服务提供者)不是由消费者自己创建的,而是由 IoC 容器在运行时动态注入到消费者中

4.IoC 使⽤

类注解:@Controller、@Service、@Repository、@Component、@Configuration.
⽅法注解:@Bean

4.1 类注解区别

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

我们发现@Service、@Repository、@Configuration.中都包含@Component说明这些注解本身属于@Component的“子类”。

4.2 ⽅法注解@Bean

1.使⽤外部包⾥的类, 没办法添加类注解

2. ⼀个类,需要多个对象,⽐如多个数据源

4.2.1⽅法注解要配合类注解使⽤

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}
}
public static void main(String[] args) {ApplicationContext context = SpringApplication.run(DemoApplication.class, args);UserInfo bean = context.getBean(UserInfo.class);System.out.println(bean);}

 

4.2.2 定义多个对象 

定义多个对象运行会报错,对象不唯一,运行失败

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}
}

 可以看出来, @Bean注解的bean,bean的名称就是它的⽅法名

@Bean可以针对同⼀个类,定义多个对象,但我们得根据他们的名称来获取bean对象 

Object userInfo1 = context.getBean("userInfo1");System.out.println(userInfo1);

4.2.3 重命名Bean 

可以通过设置name属性给Bean对象进⾏重命名操作,name={} 可以省略,也可以重命名多个名字

public class UserInfoComonent {@Bean(name = {"cxk","zhangsan"})public UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Bean(name = "mjq")public UserInfo userInfo1(){return new UserInfo("lisi",23);}
public static void main(String[] args) {ApplicationContext context = SpringApplication.run(DemoApplication.class, args);Object userInfo1 = context.getBean("cxk");System.out.println(userInfo1);}

5. DI 依赖注入

依赖注⼊,Spring给我们提供了三种⽅式:

1. 属性注⼊

2. 构造⽅法注⼊

3. Setter 注⼊

5.1 属性注⼊

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

@Service
public class UserService {public void say(){System.out.println("UserService say....");}
}
@Controller
public class UserCotroller {@Autowiredprivate UserService userService;public void say(){System.out.println("UserController say....");userService.say();}
}
UserCotroller bean = context.getBean(UserCotroller.class);
bean.say();

5.2 构造方法注入 

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如果类只有⼀个构造⽅法,那么@Autowired 注解可以省略

@Controller
public class UserCotroller {private UserService userService;public UserCotroller(UserService userService) {this.userService = userService;}public void say(){System.out.println("UserController say....");userService.say();}
}

 

如果存在多种构造方法需要添加上@Autowired 来明确指定到底使⽤哪个构造⽅法 

@Controller
public class UserCotroller {private UserService userService;public UserCotroller() {System.out.println("无参构造");}@Autowiredpublic UserCotroller(UserService userService) {this.userService = userService;System.out.println("有参构造");}public void say(){System.out.println("UserController say....");userService.say();}
}

5.3 Setter 注⼊ 

Setter 注⼊和属性的Setter⽅法实现类似,只不过在设置set⽅法的时候需要加上@Autowired 注解

@Controller
public class UserCotroller {private UserService userService;@Autowiredpublic void setUserService(UserService userService) {this.userService = userService;}public void say(){System.out.println("UserController say....");userService.say();}
}

5.4 三种注⼊优缺点 

属性注⼊

优点:简洁,使⽤⽅便

缺点:只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指 针异常)

 不能注⼊⼀个Final修饰的属性

构造函数注⼊

优点: 

可以注⼊final修饰的属性

注⼊的对象不会被修改

依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法 是在类加载阶段就会执⾏的⽅法.

通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的

缺点:

注⼊多个对象时,代码会⽐较繁琐

 Setter注⼊

优点: ⽅便在类实例之后,重新对该对象进⾏配置或者注⼊

缺点:

不能注⼊⼀个Final修饰的属性

注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的风险

5.5 @Autowired存在问题

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}
}

当同⼀类型存在多个对象时,按照名称来匹配,该类型只有一个对象时,直接注入;有多个对象时,按照名称注入

@Primary

当存在多个相同类型的Bean注⼊时,加上@Primary注解,确定哪个是默认的实现

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Primary@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}@Beanpublic UserInfo userInfo2() { return new UserInfo("cxk",34);}
}

@Qualifier

使⽤@Qualifier注解:指定当前要注⼊的bean对象。在@Qualifier的value属性中,指定注⼊的bean 的名称

@Qualifier注解不能单独使⽤,必须配合@Autowired使⽤

@Component
public class UserComponent {@Qualifier("userInfo2")@Autowiredprivate UserInfo ui;public void say(){System.out.println("UserComponent say.... ");System.out.println(ui);}
}
@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}@Beanpublic UserInfo userInfo2() { return new UserInfo("cxk",34);}
}

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}@Beanpublic String name(){return "cxk";}@Beanpublic String name1(){return "mjq";}@Beanpublic UserInfo userInfo2(@Qualifier("name") String name3) { return new UserInfo(name3,34);}
}

 

 

@Resource 

@Resource注解:是按照bean的名称进⾏注⼊。通过name属性指定要注⼊的bean的名称

@Component
public class UserInfoComonent {@Beanpublic UserInfo userInfo(){return new UserInfo("zhangsan",29);}@Beanpublic UserInfo userInfo1(){return new UserInfo("lisi",23);}
}
@Component
public class UserComponent {@Resource(name = "userInfo1")private UserInfo ui;public void say(){System.out.println("UserComponent say.... ");System.out.println(ui);}
}

 @Resource 和@Autowired区别

@Autowired是spring框架提供的注解,⽽@Resource是JDK提供的注解

@Autowired默认是按照类型注⼊,⽽@Resource是按照名称注⼊.相⽐于@Autowired 来说, @Resource ⽀持更多的参数设置,例如name设置,根据名称获取Bean.

@Autowired根据类型匹配,@Resource根据名称匹配,优先按照类型匹配,如果同类型右多个对象,再按照名称匹配,它两基本原则都是根据类型匹配,但是@Autowired不能指定名称

6.Spring, Spring Boot和SpringMVC的关系以及区别 

Spring: 简单来说,Spring是⼀个开发应⽤框架,什么样的框架呢,它轻量级、⼀ 站式、模块化,其⽬的是⽤于简化企业级应⽤程序开发,Spring的主要功能:管理对象,以及对象之间的依赖关系,⾯向切⾯编程,数据库事务管理,数据访 问,web框架⽀持等,但是Spring具备⾼度可开放性,并不强制依赖Spring,开发者可以⾃由选择Spring的部分或者全 部,Spring可以⽆缝继承第三⽅框架,⽐如MyBaties

Spring MVC:SpringMVC是Spring的⼀个⼦框架,Spring诞⽣之后,⼤家觉得很好⽤,于是按照MVC 模式设计了⼀个MVC框架(⼀些⽤Spring解耦的组件),主要⽤于开发WEB应⽤和⽹络接⼝,所以, Spring MVC是⼀个Web框架.Spring MVC基于Spring进⾏开发的,天⽣的与Spring框架集成.可以让我们更简洁的进⾏Web层 开发,⽀持灵活的URL到⻚⾯控制器的映射,提供了强⼤的约定⼤于配置的契约式编程⽀持,⾮常 容易与其他视图框架集成

Spring Boot: Spring Boot是对Spring的⼀个封装,为了简化Spring应⽤的开发⽽出现的,使⽤SpringBoot可以更加快速的搭建框架,降级开发成本,让开发 ⼈员更加专注于Spring应⽤的开发,⽽⽆需过多关注XML的配置和⼀些底层的实现 

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

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

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

相关文章

ctfshow——web(持续更新)

文章目录 1、web签到题——base64编码特征2、web2——登录框测试&sqlmap使用3、web3——php伪协议 1、web签到题——base64编码特征 查看源代码: base64编码特征:大小写数字,偶尔最后几位是。 2、web2——登录框测试&sqlmap使用 …

合约门合同全生命周期管理系统:企业智能合同管理的新时代

合约门合同全生命周期管理系统:企业智能合同管理的新时代 1. 引言 随着现代企业的快速发展,合同管理的复杂性日益增加。无论是采购合同、销售合同还是合作协议,合同管理已成为企业运营中至关重要的一环。传统的手工合同管理方式往往效率低下…

解读AVL树:平衡二叉搜索树的奥秘

✨✨小新课堂开课了,欢迎欢迎~✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C:由浅入深篇 小新的主页:编程版小新-CSDN博客 前言: 前面我们已经介绍了二叉搜…

交易逆序对的总数 ---- 分治-归并

题目链接 题目: 分析: 解法一: 暴力解法, 遍历所有的数对, 找到逆序对, 需要两重for循环, 一定会超时解法二: 归并排序的思想如果我们将数组分成两半, 我们在每一半中各找一个数字, 判断是否为逆序对, 再根据归并的思想, 再将一半数组分半, 判断是否为逆序对, 直到数组只有一…

【论文笔记】xGen-MM (BLIP-3): A Family of Open Large Multimodal Models

🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: xGen-MM (BLIP-3): A Fami…

网络编程_day3

#1024程序员节 #三次握手四次挥手#四次挥手#udp#recvfrom#sendto#服务器模型#客户端模型#Linux IO模型#阻塞式IO#非阻塞IO#设置非阻塞的方式 目录 【0】复习 【1】三次握手四次挥手 四次挥手 四次挥手既可以由客户端发起,也可以由服务器发起 【2】udp 1. 通信流程 2…

实验:使用Oxygen发布大型手册到Word格式

此前,我曾发表过一篇文章《结构化文档发布的故事和性能调优》,文中讨论了在将大型DITA手册转换为PDF格式时可能遇到的性能挑战及相应的优化策略。 近日,有朋友咨询,若将同样的大型手册输出为MS Word格式,是否也会面临…

Linux复习-C++

参考博客: https://blog.csdn.net/qq_45254369/article/details/126023482?ops_request_misc%257B%2522request%255Fid%2522%253A%252277629891-A0F3-4EFC-B1AC-410093596085%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&req…

[JAVAEE] 多线程的案例(一)-单例模式

目录 一. 单例模式 二. 单例模式的使用时机 三. 单例模式的关键代码 四. 单例模式的几种实现方式 4.1 饿汉方式(急) 4.2 懒汉模式(缓) a. 解决原子性的问题 b. 解决程序运行效率低下的问题 c. 解决指令重排序的问题(其次是为了解决内存可见性的问题) 五. 总结 一. …

HCIP-HarmonyOS Application Developer 习题(十七)

(判断)1、对于用户创建的一些临时卡片在遇到卡片服务框架死亡重启,此时临时卡片数据在卡片管理服务中已经删除,且对应的卡片ID不会通知到提供方,所以卡片使用方需要自己负责清理长时间未刚除的临时卡片数据。 答案&…

QT:MaintenanceTool 模块安装工具

QT的MaintenanceTool 工具对已安装的 Qt 进行卸载、修复等其他操作时提示At least one valid and enabled repository required for this action to succeed 解决方式:在设置中添加一个临时的仓库 https://mirrors.tuna.tsinghua.edu.cn/qt/online/qtsdkrepositor…

6,000 个网站上的假 WordPress 插件提示用户安装恶意软件

黑客使用窃取的凭证感染 WordPress 网站,并向其发送虚假插件,通过虚假的浏览器更新提示向最终用户发送恶意软件和信息窃取程序。 该恶意活动基于ClickFix假浏览器更新恶意软件的新变种,自 2024 年 6 月以来已使用假 WordPress 插件感染了超过…

放大器和基本运放电路的公式推导

放大器和基本运放电路的公式推导 放大器全家谱运放的渊源和数学分析基本运放电路的公式推导预备知识基本特性跟随器特性比较器特性 基本运放电路反相放大器(反比例运算放大器)同相放大器(正比例运算放大器)反相加法器同相加法器减…

Python条形图 | 指标(特征)重要性图的绘制

在数据科学和机器学习的工作流程中,特征选择是一个关键步骤。通过评估每个特征对模型预测能力的影响,我们可以选择最有意义的特征(指标),从而提高模型的性能并减少过拟合。本文将介绍如何使用 Python 的 Seaborn 和 Ma…

go 使用fyne实现桌面程序的计算器例子

使用Fyne工具包构建跨平台应用是非常简单的,在此之前我们需要做一些准备功能做,比如安装一些gcc基础图形依赖库,还有go语言本身的运行开发环境都是必要的。 在此之前我们希望你是go语言的已入门用户,掌握go的协程,管道…

Linux基础知识 - C(自学使用)

1.C语言基础知识 参考博客: https://blog.csdn.net/qq_45254369/article/details/126023482?ops_request_misc%257B%2522request%255Fid%2522%253A%252277629891-A0F3-4EFC-B1AC-410093596085%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%…

Xcode文件默认存储位置-使用c++file保存文件默认路径以及设置为路径为当前项目路径

Xcode文件默认存储位置-使用cfile保存文件默认路径以及设置为路径为当前项目路径 1.概述 使用Xcode工具开发时候,遇到C调用file创建文件后,在当前项目中找不到文件路径。这是由于xcode会将文件保存到默认设置的路径。下面是查看文件默认存储路径和修改…

DC-9靶场渗透

靶机:DC-9 DC: 9 ~ VulnHub 攻击机:kail linux 2024 1,将两台虚拟机网络连接都改为NAT模式,并查看DC-9的MAC地址 2,进行主机扫描,通过MAC地址发现靶机的IP地址 攻击机IP地址192.168.23.169,靶机IP地址192.1…

MySQL-存储过程/函数/触发器

文章目录 什么是存储过程存储过程的优缺点存储过程的基本使用存储过程的创建存储过程的调用存储过程的删除存储过程的查看delimiter命令 MySQL中的变量系统变量用户变量局部变量参数 if语句case语句while循环repeat循环loop循环游标cursor捕获异常并处理存储函数触发器触发器概…

16. 虚拟化

文章目录 第16章 虚拟化16.1 共享资源16.2 虚拟机16.3 虚拟机镜像16.4 容器16.5 容器和虚拟机16.6 容器的可移植性16.7 Pod(容器组)16.8 无服务器架构16.9 小结16.10 扩展阅读16.11 问题讨论 第16章 虚拟化 “虚拟”意味着永远不知道你的下一个字节从哪里…