依赖注入方式

news2024/12/23 20:37:15

Spring中有哪些注入方式?

我们先来思考

向一个类中传递数据的方式有几种?

  • 普通方法(set方法)
  • 构造方法

依赖注入描述了在容器中建立bean与bean之间的依赖关系的过程,如果bean运行需要的是数字或
字符串呢?

  • 引用类型
  • 简单类型(基本数据类型与String)

Spring就是基于上面这些知识点,为我们提供了两种注入方式,分别是:

setter注入

  • 简单类型
  • 引用类型

构造器注入

  • 简单类型
  • 引用类型

依赖注入的方式已经介绍完,接下来挨个学习下:

setter注入  

1. 对于setter方式注入引用类型的方式之前已经学习过,快速回顾下:

在bean中定义引用类型属性,并提供可访问的set方法

1 public class BookServiceImpl implements BookService {

2     private BookDao bookDao;

3     public void setBookDao(BookDao bookDao) {

4         this.bookDao = bookDao;

5     }

6 }

 配置中使用property标签ref属性注入引用类型对象

1 <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

2     <property name="bookDao" ref="bookDao"/>

3 </bean>

4  

5 <bean id="bookDao" class="com.itheima.dao.imipl.BookDaoImpl"/>

 

环境准备  

为了更好的学习下面内容,我们依旧准备一个新环境:

  • 创建一个Maven项目
  • pom.xml添加依赖
  • resources下添加spring的配置文件

这些步骤和前面的都一致,大家可以快速的拷贝即可,最终项目的结构如下:

(1)项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和
BookServiceImpl类

1 public interface BookDao {

2     public void save();

3 }

4  

5 public class BookDaoImpl implements BookDao {

6     public void save() {

7         System.out.println("book dao save ...");

8     }

9 }

10 public interface UserDao {

11     public void save();

12 }

13 public class UserDaoImpl implements UserDao {

14     public void save() {

15         System.out.println("user dao save ...");

16     }

17 }

18  

19 public interface BookService {

20     public void save();

21 }

22  

23 public class BookServiceImpl implements BookService{

24     private BookDao bookDao;

25  

26     public void setBookDao(BookDao bookDao) {

27         this.bookDao = bookDao;

28     }

29  

30     public void save() {

31         System.out.println("book service save ...");

32         bookDao.save();

33     }

34 }

(2)resources下提供spring的配置文件

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

7     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

8         <property name="bookDao" ref="bookDao"/>

9     </bean>

10 </beans>

(3)编写AppForDISet运行类,加载Spring的IOC容器,并从中获取对应的bean对象

1 public class AppForDISet {

2     public static void main( String[] args ) {

3         ApplicationContext ctx = new 

ClassPathXmlApplicationContext("applicationContext.xml");

4         BookService bookService = (BookService) ctx.getBean("bookService");

5         bookService.save();

6     }

7 }

接下来,在上面这个环境中来完成setter注入的学习:

注入引用数据类型  

需求:在bookServiceImpl对象中注入userDao

1.在BookServiceImpl中声明userDao属性

2.为userDao属性提供setter方法

3.在配置文件中使用property标签注入

步骤1:声明属性并提供setter方法  

在BookServiceImpl中声明userDao属性,并提供setter方法

1 public class BookServiceImpl implements BookService{

2     private BookDao bookDao;

3     private UserDao userDao;

4     

5     public void setUserDao(UserDao userDao) {

6         this.userDao = userDao;

7     }

8     public void setBookDao(BookDao bookDao) {

9         this.bookDao = bookDao;

10     }

11  

12     public void save() {

13         System.out.println("book service save ...");

14         bookDao.save();

15         userDao.save();

16     }

17 }

步骤2:配置文件中进行注入配置  

在applicationContext.xml配置文件中使用property标签注入

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

7     <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

8     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

9         <property name="bookDao" ref="bookDao"/>

10         <property name="userDao" ref="userDao"/>

11     </bean>

12 </beans>

步骤3:运行程序  

运行AppForDISet类,查看结果,说明userDao已经成功注入。

注入简单数据类型  

需求:给BookDaoImpl注入一些简单数据类型的数据

参考引用数据类型的注入,我们可以推出具体的步骤为:

1.在BookDaoImpl类中声明对应的简单数据类型的属性

2.为这些属性提供对应的setter方法

3.在applicationContext.xml中配置

思考:

引用类型使用的是<property name="" ref=""/>,简单数据类型还是使用ref么?

ref是指向Spring的IOC容器中的另一个bean对象的,对于简单数据类型,没有对应的bean对象,
该如何配置?

步骤1:声明属性并提供setter方法  

在BookDaoImpl类中声明对应的简单数据类型的属性,并提供对应的setter方法

1 public class BookDaoImpl implements BookDao {

2  

3     private String databaseName;

4     private int connectionNum;

5  

6     public void setConnectionNum(int connectionNum) {

7         this.connectionNum = connectionNum;

8     }

9  

10     public void setDatabaseName(String databaseName) {

11         this.databaseName = databaseName;

12     }

13  

14     public void save() {

15         System.out.println("book dao save 

..."+databaseName+","+connectionNum);

16     }

17 }

  

步骤2:配置文件中进行注入配置  

在applicationContext.xml配置文件中使用property标签注入

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

7         <property name="databaseName" value="mysql"/>

8         <property name="connectionNum" value="10"/>

9     </bean>

10     <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

11     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

12         <property name="bookDao" ref="bookDao"/>

13         <property name="userDao" ref="userDao"/>

14     </bean>

15 </beans>

 名称 值

 只要你用了value,你就可以不用管它的类型了,spring自动帮我们配置好了

说明:

value:后面跟的是简单数据类型,对于参数类型,Spring在注入的时候会自动转换,但是不能写成

1 <property name="connectionNum" value="abc"/>

这样的话,spring在将abc转换成int类型的时候就会报错。

步骤3:运行程序  

运行AppForDISet类,查看结果,说明userDao已经成功注入。

注意:两个property注入标签的顺序可以任意。

对于setter注入方式的基本使用就已经介绍完了,

  • 对于引用数据类型使用的是<property name="" ref=""/>
  • 对于简单数据类型使用的是<property name="" value=""/>

构造器注入  

环境准备  

构造器注入也就是构造方法注入,学习之前,还是先准备下环境:

  • 创建一个Maven项目
  • pom.xml添加依赖
  • resources下添加spring的配置文件

这些步骤和前面的都一致,大家可以快速的拷贝即可,最终项目的结构如下:

 (1)项目中添加BookDao、BookDaoImpl、UserDao、UserDaoImpl、BookService和
BookServiceImpl类

1 public interface BookDao {

2     public void save();

3 }

4  

5 public class BookDaoImpl implements BookDao {

6     

7     private String databaseName;

8     private int connectionNum;

9     

10     public void save() {

11         System.out.println("book dao save ...");

12     }

13 }

14 public interface UserDao {

15     public void save();

16 }

17 public class UserDaoImpl implements UserDao {

18     public void save() {

19         System.out.println("user dao save ...");

20     }

21 }

22  

23 public interface BookService {

24     public void save();

25 }

26  

27 public class BookServiceImpl implements BookService{

28     private BookDao bookDao;

29  

30     public void setBookDao(BookDao bookDao) {

31         this.bookDao = bookDao;

32     }

33  

34     public void save() {

35         System.out.println("book service save ...");

36         bookDao.save();

37     }

38 }

 右击Constructor构造器生成 

(2)resources下提供spring的配置文件

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

7     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

8         <property name="bookDao" ref="bookDao"/>

9     </bean>

10 </beans>

(3)编写AppForDIConstructor运行类,加载Spring的IOC容器,并从中获取对应的bean对象

1 public class AppForDIConstructor {

2     public static void main( String[] args ) {

3         ApplicationContext ctx = new 

ClassPathXmlApplicationContext("applicationContext.xml");

4         BookService bookService = (BookService) ctx.getBean("bookService");

5         bookService.save();

6     }

7 }

构造器注入引用数据类型  

接下来,在上面这个环境中来完成构造器注入的学习:

需求:将BookServiceImpl类中的bookDao修改成使用构造器的方式注入。

1.将bookDao的setter方法删除掉

2.添加带有bookDao参数的构造方法

3.在applicationContext.xml中配置

步骤1:删除setter方法并提供构造方法  

在BookServiceImpl类中将bookDao的setter方法删除掉,并添加带有bookDao参数的构造方法

1 public class BookServiceImpl implements BookService{

2     private BookDao bookDao;

3  

4     public BookServiceImpl(BookDao bookDao) {

5         this.bookDao = bookDao;

6     }

7  

8     public void save() {

9         System.out.println("book service save ...");

10         bookDao.save();

11     }

12 }

步骤2:配置文件中进行配置构造方式注入  

在applicationContext.xml中配置

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

7     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

8         <constructor-arg name="bookDao" ref="bookDao"/>

9     </bean>

10 </beans>

说明:

标签中

  • name属性对应的值为构造函数中方法形参的参数名,必须要保持一致。
  • ref属性指向的是spring的IOC容器中其他bean对象。

步骤3:运行程序  

运行AppForDIConstructor类,查看结果,说明bookDao已经成功注入。

构造器注入多个引用数据类型  

需求:在BookServiceImpl使用构造函数注入多个引用数据类型,比如userDao

1.声明userDao属性

2.生成一个带有bookDao和userDao参数的构造函数

3.在applicationContext.xml中配置注入

步骤1:提供多个属性的构造函数  

在BookServiceImpl声明userDao并提供多个参数的构造函数

1 public class BookServiceImpl implements BookService{

2     private BookDao bookDao;

3     private UserDao userDao;

4  

5     public BookServiceImpl(BookDao bookDao,UserDao userDao) {

6         this.bookDao = bookDao;

7         this.userDao = userDao;

8     }

9  

10     public void save() {

11         System.out.println("book service save ...");

12         bookDao.save();

13         userDao.save();

14     }

15 }

步骤2:配置文件中配置多参数注入

在applicationContext.xml中配置注入

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>

7     <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

8     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

9         <constructor-arg name="bookDao" ref="bookDao"/>

10         <constructor-arg name="userDao" ref="userDao"/>

11     </bean>

12 </beans>

说明:这两个<contructor-arg>的配置顺序可以任意

步骤3:运行程序  

运行AppForDIConstructor类,查看结果,说明userDao已经成功注入。

构造器注入多个简单数据类型  

需求:在BookDaoImpl中,使用构造函数注入databaseName和connectionNum两个参数。

参考引用数据类型的注入,我们可以推出具体的步骤为:

1.提供一个包含这两个参数的构造方法

2.在applicationContext.xml中进行注入配置

步骤1:添加多个简单属性并提供构造方法  

修改BookDaoImpl类,添加构造方法

1 public class BookDaoImpl implements BookDao {

2     private String databaseName;

3     private int connectionNum;

4  

5     public BookDaoImpl(String databaseName, int connectionNum) {

6         this.databaseName = databaseName;

7         this.connectionNum = connectionNum;

8     }

9  

10     public void save() {

11         System.out.println("book dao save 

..."+databaseName+","+connectionNum);

12     }

13 }

步骤2:配置完成多个属性构造器注入  

在applicationContext.xml中进行注入配置

1 <?xml version="1.0" encoding="UTF-8"?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4        xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd">

5  

6     <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

7         <constructor-arg name="databaseName" value="mysql"/>

8         <constructor-arg name="connectionNum" value="666"/>

9     </bean>

10     <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>

11     <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">

12         <constructor-arg name="bookDao" ref="bookDao"/>

13         <constructor-arg name="userDao" ref="userDao"/>

14     </bean>

15 </beans>

说明:这两个<contructor-arg>的配置顺序可以任意

步骤3:运行程序  

运行AppForDIConstructor类,查看结果

上面已经完成了构造函数注入的基本使用,但是会存在一些问题:

  •  当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变
  • 这两块存在紧耦合,具体该如何解决?

在解决这个问题之前,需要提前说明的是,这个参数名发生变化的情况并不多,所以上面的还是比较
主流的配置方式,下面介绍的,大家都以了解为主。

方式一:删除name属性,添加type属性,按照类型注入

1 <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

2     <constructor-arg type="int" value="10"/>

3     <constructor-arg type="java.lang.String" value="mysql"/>

4 </bean>

  

  • 这种方式可以解决构造函数形参名发生变化带来的耦合问题
  • 但是如果构造方法参数中有类型相同的参数,这种方式就不太好实现了

方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始

1 <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">

2     <constructor-arg index="1" value="100"/>

3     <constructor-arg index="0" value="mysql"/>

4 </bean>

  • 这种方式可以解决参数类型重复问题
  • 但是如果构造方法参数顺序发生变化后,这种方式又带来了耦合问题

介绍完两种参数的注入方式,具体我们该如何选择呢?

1. 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现

强制依赖指对象在创建的过程中必须要注入指定的参数
2. 可选依赖使用setter注入进行,灵活性强

可选依赖指对象在创建过程中注入的参数可有可无
3. Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相

对严谨

4. 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选
依赖的注入

5. 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注

6. 自己开发的模块推荐使用setter注入

这节中主要讲解的是Spring的依赖注入的实现方式:

setter注入

简单数据类型

1 <bean ...>

2     <property name="" value=""/>

3 </bean>

引用数据类型

1 <bean ...>

2     <property name="" ref=""/>

3 </bean>

构造器注入

简单数据类型

1 <bean ...>

2     <constructor-arg name="" index="" type="" value=""/>

3 </bean>

引用数据类型

1 <bean ...>

2     <constructor-arg name="" index="" type="" ref=""/>

3 </bean>

依赖注入的方式选择上

  • 建议使用setter注入
  • 第三方技术根据情况选择

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

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

相关文章

Primo Ramdisk内存盘工具软件

简介 Primo Ramdisk 软件的主要功能是通过独特的软件算法将物理内存模拟成一个超快速的硬盘&#xff0c;在这个虚拟硬盘上的读写操作均在内存中完成。由于物理内存的访问速度远远超过物理硬盘&#xff0c;因此虚拟硬盘具有非常高的数据读写速度&#xff0c;从而突破系统IO瓶颈&…

“SCSA-T学习导图+”系列:下一代防火墙

本期引言&#xff1a; 近年来&#xff0c;随着数字化业务带给我们高效和便捷的同时&#xff0c;信息暴露面的增加、网络边界的模糊化以及黑客攻击的产业化&#xff0c;使得网络安全事件相较以往成指数级增加。传统防火墙基于五元组的方式对进出网络的数据流量进行访问控制&…

医院影像图像科室工作站PACS系统 DICOM 三维图像后处理与重建

PACS报告系统的主要任务是通过运用不断积累诊断常用语&#xff0c;减轻出报告的劳动强度&#xff0c;并且将报告保存成电子文档以便日后查阅。在PACS的报告系统中&#xff0c;有三种不同层次的方法输入文字—“高级模板”、“分类词条”和“短语词典”。这三种方法的内容都可以…

记一次从JS到内网的横向案例

前言 前段时间参加了一场攻防演练&#xff0c;使用常规漏洞尝试未果后&#xff0c;想到不少师傅分享过从JS中寻找突破的文章&#xff0c;于是硬着头皮刚起了JS&#xff0c;最终打开了内网入口获取了靶标权限和个人信息。在此分享一下过程。 声明&#xff1a;本次演练中&#xf…

C/C++每日一练(20230422)

目录 1. 存在重复元素 &#x1f31f; 2. 组合总和 &#x1f31f;&#x1f31f; 3. 给表达式添加运算符 &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日…

java基于J2EE的学生宿舍信息管理系统

本目 录 摘 要 I ABSTRACT II 第一章 绪论 1 1.1课题研究背景 1 1.2课题的目的和意义 1 1.3开发工具及简介 2 1.3.1开发工具 2 1.3.2 JSP技术 3 1.3.3 JavaScript 4 第二章 需求分析 4 2.1可行性分析 4 2.1.1技术的可行性 4 2.1.2经济的…

Faster RCNN系列1——Anchor生成过程

Faster RCNN系列&#xff1a; Faster RCNN系列1——Anchor生成过程 Faster RCNN系列2——RPN的真值与预测值概述 Faster RCNN系列3——RPN的真值详解与损失值计算 Faster RCNN系列4——生成Proposal与RoI Faster RCNN系列5——RoI Pooling与全连接层 一、RPN模块概述 RPN模块…

jsp946+java物流信息管理平台-sqlserver

本系统是一个独立的系统&#xff0c;用来解决物流信息信息的管理问题。采用JSP技术构建了一个有效而且实用的物流信息信息管理平台&#xff0c;目的是为高效地完成对物流信息信息的管理。 1、内部办公功能&#xff1a;包含工作计划、通告管理、公文管理&#xff1b; 包括可以…

手机录音误删怎么恢复?恢复录音,就这么简单!

案例&#xff1a;手机录音删除了还能恢复吗&#xff1f; 【友友们&#xff0c;苹果手机录音删除了还可以恢复吗&#xff1f;里面有一些关于会议记录的录音&#xff0c;不小心被我删了&#xff0c;有哪些方法可以快速恢复录音文件&#xff1f;】 如果您在使用iPhone手机录音时误…

Python小姿势 - ### Python之禅

Python之禅 Python之禅&#xff08;The Zen of Python&#xff09;是Python之父Guido van Rossum所著的一篇文章&#xff0c;总结了Python语言的哲学。 文章开头写道&#xff1a; Beautiful is better than ugly. Explicit is better than implicit. Simple is better than com…

代码随想录--字符串--反转字符串题型

反转字符串 不能给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 我们直接用双指针&#xff0c;一个指头一个指尾&#xff0c;swap交换&#xff0c;然后同时往中间走一步再进入循环交换即可。 反转字符串II 这道题我们容…

linux(18.04)编译安装python3.6的全过程,pip python不与linux系统环境混乱

因为使用要求&#xff0c;使得我需要在linux环境下安装一个独立的python环境&#xff0c;不干扰其他环境。 一&#xff0c;下载python资源包 两种下载方式二选一&#xff0c;谁快选谁 linux下载&#xff1a; 不同的python版本&#xff0c;安装过程是一样的&#xff0c;下载…

蒙层禁止页面滚动

学习链接&#xff1a;蒙层禁止页面滚动的方案 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta name"viewport" content"widthdevice-width, initial-scale1"><title>蒙层禁止页面滚动的方案<…

Map Reduce高级篇:Join-Reduce

Join关联操作 背景 在实际的数据库应用中&#xff0c;我们经常需要从多个数据表中读取数据&#xff0c;这时就可以使用SQL语句中的连接&#xff08;JOIN&#xff09;&#xff0c;在两个或者多个数据表中查询数据。在使用MapReduce框架进行数据查询的过程中&#xff0c;也会涉…

React Refs

React 支持一种非常特殊的属性 Ref &#xff0c;可以用来绑定到 render() 输出的任何组件上。 这个特殊的属性允许引用 render() 返回的相应的支撑实例 &#xff08; backing instance &#xff09;。这样就可以确保在任何时间总是拿到正确的实例。 使用&#xff1a; 绑定一…

Linux基础—DHCP原理与配置

Linux基础—DHCP原理与配置 一、DHCP工作原理1.了解DHCP服务使用DHCP的优势DHCP的分配方式 2.DHCP的IP地白动获取工作原理: 二、配置DHCP服务器三、DHCP场景应用实验 一、DHCP工作原理 1.了解DHCP服务 DHCP(Dynamic HostConfiguration Protocol&#xff0c;动态主机配置协议) …

网络基础入门

目录 网络存在的意义 网络发展 网络在哪里&#xff1f; 网络是分层的 理解分层 软件可以分层 网络协议栈也是层状结构 认识协议 协议是什么 协议分层 网络传输需要解决的四个问题 OSI七层模型&#xff08;了解为主&#xff09; TCP/IP五层&#xff08;或四层&…

LVS --一文精通

目录 dns解析 下一跳机制 LVS:NAT LVS: IP TUN隧道 LVS: DR DR> TUN > NAT > FULL NAT dns解析 DNS本地域名服务器&#xff0c;当用户访问一个网址&#xff0c;计算机就会提出域名解析请求&#xff0c;并发给本地域名服务器&#xff0c;本地域名服务器收到请求…

你真正了解低代码么?(国内低代码平台状况分析)

■ 写在前面■ 低代码产品如何分类&#xff0c;90% 的人都没有搞清楚■ 低代码平台如何比较&#xff1f;Point 在哪儿&#xff1f;一个比喻大家全听懂■ “拼”出来的低代码平台&#xff0c;真的好用吗&#xff1f;■ 推荐一款 C 端低代码产品 ■ 写在前面 都说技术是生产力&a…

每日一个小技巧:1分钟告诉你如何给黑白照片上色

你是否有过这样的经历&#xff1a;在家翻出爷爷奶奶的旧照片时&#xff0c;发现它们都是黑白色的&#xff0c;无法体现当时的真实色彩&#xff1f;由于一些老照片的拍摄时间较早&#xff0c;因此都是以黑白形式存在的&#xff0c;这样的照片不仅影响观感&#xff0c;还抑制了我…