SpringBoot容器--注解的使用

文章目录

  • 容器功能--注解
    • Spring 注入组件的注解
      • @Component、@Controller、@Service、@Repository
      • 案例演示
    • @Configuration
      • 应用实例
        • 传统方式应用实例
        • 使用SpringBoot 的@Configuration 添加/注入组件
      • @Configuration 注意事项和细节
    • @Import
      • 应用实例
    • @Conditional
      • @Conditional 介绍
      • 应用实例
    • @ImportResource
      • @ImportResource 应用实例
    • 配置绑定
      • 应用实例
      • 注意事项和细节

容器功能–注解

Spring 注入组件的注解

@Component、@Controller、@Service、@Repository

说明: 这些在Spring 中的传统注解仍然有效,通过这些注解可以给容器注入组件

案例演示

  1. 创建quickstart\src\main\java\com\nlc\springboot\bean\A.java

image-20230805210154808

其他的就不做演示了

  1. 在quickstart\src\main\java\com\nlc\springboot\MainApp.java 获取, 完成测试

image-20230805210818355

@Configuration

应用实例

传统方式应用实例

说明: 演示在SpringBoot, 如何通过@Configuration 创建配置类来注入组件

回顾传统方式如何通过配置文件注入组件

1.创建quickstart\src\main\java\com\nlc\springboot\bean\Monster.java

public class Monster {private Integer id;private String name;private Integer age;private String skill;public Monster(Integer id, String name, Integer age, String skill) {this.id = id;this.name = name;this.age = age;this.skill = skill;}public Monster() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getSkill() {return skill;}public void setSkill(String skill) {this.skill = skill;}@Overridepublic String toString() {return "Monster{" +"id=" + id +", name='" + name + '\'' +", age=" + age +", skill='" + skill + '\'' +'}';}
}
  1. 创建quickstart\src\main\resources\beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置了Monster bean--><bean id="monster03" class="com.nlc.springboot.bean.Monster"><property name="name" value="牛魔王~"></property><property name="age" value="5000"></property><property name="skill" value="芭蕉扇~"></property><property name="id" value="1000"></property></bean>
</beans>

使用SpringBoot 的@Configuration 添加/注入组件

  1. 创建quickstart\src\main\java\com\nlc\springboot\config\BeanConfig.java

程序员可以通过@Bean 注解注入bean对象到容器。

当一个类被 @Configuration 标识,该类-Bean 也会注入容器。

//@Configuration 标识这是一个配置类: 等价配置文件
@Configuration
public class BeanConfig {/*** 解读* 1. @Bean : 给容器添加组件, 就是Monster bean* 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id* 3. Monster : 注入类型, 注入bean的类型是Monster* 4. new Monster(200,"牛魔王",500,"疯魔拳") 注入到容器中具体的Bean信息* 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字/id monster_nmw* 6. 默认是单例注入* 7. 通过 @Scope("prototype")  可以每次返回新的对象,就多例.*///@Bean(name = "monster_nmw")@Bean//@Scope("prototype")public Monster monster01() {return new Monster(200, "牛魔王", 500, "疯魔拳");}
}

2.修改MainApp.java , 从配置文件/容器获取bean , 并完成测试

 public static void main(String[] args) {//启动springboot应用程序/项目ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);//1. ioc.getBean("monster01", Monster.class) 是从BeanConfig 配置类/容器获取bean实例//2. 默认是单列模式, 所以monster01 == monster02//获取BeanConfig 配置类的组件/bean 实例Monster monster01 = ioc.getBean("monster01", Monster.class);System.out.println(monster01);Monster monster02 = ioc.getBean("monster01", Monster.class);System.out.println(monster01 == monster02);
}
  1. 也可以通过Debug 来查看ioc 容器是否存在monster01 Bean 实例

image-20230805212207663

image-20230805212218978

image-20230805212231858

image-20230805212244577

beanDefinitionMap, 只是存放了bean 定义信息, 真正存放Bean 实例的在singleonObjectis的Map 中, 对于非单例,是每次动态反射生成的实例

image-20230805212310024

image-20230805212325251

@Configuration 注意事项和细节

  1. 配置类本身也是组件, 因此也可以获取, 测试修改MainApp.java
public static void main(String[] args) {ConfigurableApplicationContext ioc =  SpringApplication.run(MainApp.class, args);//1. ioc.getBean("monster01", Monster.class) 是从BeanConfig 配置类/容器获取bean 实例//2. 默认是单列模式, 所以monster01 == monster02//获取BeanConfig 配置类的组件/bean 实例Monster monster01 = ioc.getBean("monster01", Monster.class);System.out.println(monster01);Monster monster02 = ioc.getBean("monster01", Monster.class);System.out.println(monster01 == monster02);//配置类本身也是组件, 因此也可以获取BeanConfig beanConfig = ioc.getBean(BeanConfig.class);System.out.println("beanConfig= " + beanConfig);
}
  1. SpringBoot2 新增特性: proxyBeanMethods 指定Full 模式和Lite 模式

修改quickstart\src\main\java\com\nlc\springboot\config\BeanConfig.java

/***  * 1. proxyBeanMethods:代理bean的方法*  * (1) Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式】*  * (2) Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的, 是非代理方式】*  * (3) 特别说明: proxyBeanMethods 是在 调用@Bean方法 才生效,因此,需要先获取BeanConfig 组件,再调用方法*  * 而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 注意观察直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值不会生效*  * (4) 如何选择: 组件依赖必须使用Full模式默认。如果不需要组件依赖使用 Lite模式*  * (5) Lite模 也称为轻量级模式,因为不检测依赖关系,运行速度快*/
//@Configuration 标识这是一个配置类: 等价配置文件
@Configuration(proxyBeanMethods = false)
public class BeanConfig {/*** 解读* 1. @Bean : 给容器添加组件, 就是Monster bean* 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id* 3. Monster : 注入类型, 注入bean的类型是Monster* 4. new Monster(200,"牛魔王",500,"疯魔拳") 注入到容器中具体的Bean信息* 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字/id monster_nmw* 6. 默认是单例注入* 7. 通过 @Scope("prototype")  可以每次返回新的对象,就多例.*///@Bean(name = "monster_nmw")@Bean//@Scope("prototype")public Monster monster01() {return new Monster(200, "牛魔王", 500, "疯魔拳");}
}
  1. 修改quickstart\src\main\java\com\nlc\springboot\MainApp.java
@SpringBootApplication(scanBasePackages = "com.nlc")
public class MainApp {public static void main(String[] args) {//启动SpringBoot 应用程序ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);//1. ioc.getBean("monster01", Monster.class) 是从BeanConfig 配置类/容器获取bean实例//2. 默认是单列模式, 所以monster01 == monster02//获取BeanConfig 配置类的组件/bean 实例Monster monster01 = ioc.getBean("monster01", Monster.class);System.out.println(monster01);Monster monster02 = ioc.getBean("monster01", Monster.class);System.out.println(monster01 == monster02);//配置类本身也是组件, 因此也可以获取,monster01 != monster02//上面配置了@Configuration(proxyBeanMethods = false),获取到的都是新创建的BeanConfig beanConfig = ioc.getBean(BeanConfig.class);System.out.println("beanConfig= " + beanConfig);Monster monster03 = beanConfig.monster01();Monster monster04 = beanConfig.monster01();System.out.println("monster03 == monster04 : " + (monster03 == monster04));}
}
  1. 配置类可以有多个, 就和Spring 可以有多个ioc 配置文件是一个道理.

创建quickstart\src\main\java\com\nlc\springboot\config\BeanConfig2.java

@Configuration
public class BeanConfig2 {@Beanpublic Monster monster100() {return new Monster(200, "牛魔王~~", 500, "芭蕉扇");}
}

完成测试quickstart\src\main\java\com\nlc\springboot\MainApp.java

@SpringBootApplication
public class MainApp {public static void main(String[] args) {//启动SpringBoot 应用程序ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);Monster monster100 = ioc.getBean("monster100", Monster.class);System.out.println(monster100);}
}

image-20230805215006417

@Import

应用实例

说明: 演示在SpringBoot, 如何通过@Import 来注入组件

创建quickstart\src\main\java\com\nlc\springboot\bean\Cat.java

public class Cat {
}

创建quickstart\src\main\java\com\nlc\springboot\bean\Dog.java

public class Dog {
}
  1. 修改BeanConfig.java 通过@Import 注入组件
/**
* Import 可以传入一个数组,可以一次注入多个组件
* public @interface Import {
* Class<?>[] value();
* }
* 注意@Import 方式注入的组件, 默认组件的名字就是全类名
*/
@Import({Dog.class, Cat.class})
// @Configuration//标识这是一个配置类: 等价配置文件
@Configuration(proxyBeanMethods = false)
public class BeanConfig {
}
  1. 修改MainApp.java 完成测试
public static void main(String[] args) {//启动springboot应用程序/项目ConfigurableApplicationContext ioc =SpringApplication.run(MainApp.class, args);Dog dogBean = ioc.getBean(Dog.class);Cat catBean = ioc.getBean(Cat.class);System.out.println("dogBean--" + dogBean);System.out.println("catBean--" + catBean);
}

默认类型导入是单例的,如果有多个同类型bean就会报错。

@Conditional

@Conditional 介绍

  1. 条件装配:满足Conditional 指定的条件,则进行组件注入
  2. @Conditional 是一个根注解,下面有很多扩展注解

image-20230806113131984

image-20230806113154171

应用实例

  1. 要求: 演示在SpringBoot, 如何通过@ConditionalOnBean 来注入组件
  2. 只有在容器中有name = monster_nmw 组件时,才注入dog01, 代码如图

image-20230806113251428

@Bean
public Dog dog01() {return new Dog();
}
  1. 先测试下,当前是否能注入dog01

image-20230806113503712

System.out.println("容器是否注入了dog01= " + ioc.containsBean(“dog01”));

4.修改BeanConfig.java , 加入@ConditionalOnBean 条件约束,并完成测试

@Import({Dog.class, Cat.class})
// @Configuration//标识这是一个配置类: 等价配置文件
@Configuration(proxyBeanMethods = false)
//设置每次获取bean都创建新的,要符合条件才生效
public class BeanConfig {/*** 1. @Bean : 给容器中添加组件* 2. monster01() : 默认方法名作为组件的id* 3. Monster: 返回类型就是组件类型, 返回的值就是new Monster(100, "牛魔王", 500, "芭蕉扇")* 4. @Bean("monster_nmw"): 重新指定组件的id = “monster_nmw”* 5. 配置类里面使用@Bean 标注在方法上给容器注册组件,默认是单实例的*/// @Bean("monster_nmw")@Beanpublic Monster monster01() {return new Monster(100, "牛魔王", 500, "芭蕉扇");}/*** @ConditionalOnBean(name = "monster_nmw"):* 1. 表示只有容器中注入了name = monster_nmw 的组件,下面的组件(dog01)才会被注入* 2. @ConditionalOnBean(name = "monster_nmw") 也可以放在类名处,* 则表示对该配置类中所有要注入的组件都进行条件约束* 3. 还有很多其它条件约束注解,用到时在讲解.*/@ConditionalOnBean(name = "monster_nmw")@Beanpublic Dog dog01() {return new Dog();}
}

自己测试,打开注解,看是否注入。

@ImportResource

作用:原生配置文件引入, 也就是可以直接导入Spring 传统的beans.xml ,可以认为是SpringBoot 对Spring 容器文件的兼容.

@ImportResource 应用实例

  1. 需求: 将beans.xml 导入到BeanConfig.java 配置类, 并测试是否可以获得beans.xml注入/配置的组件

将beans.xml放在resource资源目录下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置了Monster bean--><bean id="monster03" class="com.nlc.springboot.bean.Monster"><property name="name" value="牛魔王~"></property><property name="age" value="5000"></property><property name="skill" value="芭蕉扇~"></property><property name="id" value="1000"></property></bean>
</beans>
  1. 修改BeanConfig.java / 或者创建新的BeanConfig3.java(建议创建新的配置类) 来测试,使用@ImportResource 导入beans.xml
//外部导入bean
@Import({Dog.class, Cat.class})
// @Configuration//标识这是一个配置类: 等价配置文件
@Configuration(proxyBeanMethods = false)
//导入beans.xml
@ImportResource("classpath:beans.xml")
public class BeanConfig {
}
  1. 在MainApp.java 测试
public static void main(String[] args) {ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);System.out.println("容器是否注入了dog01= " + ioc.containsBean("dog01"));System.out.println("monster03: " + ioc.containsBean("monster03"));System.out.println(ioc.getBean("monster03"));
}

配置绑定

说明:使用Java 读取到SpringBoot 核心配置文件application.properties 的内容,并且把它封装到JavaBean 中

应用实例

  1. 需求: 将application.properties 指定的k-v 和JavaBean 绑定
#默认server.port=8080
server.port=10000
#比如: 默认spring.servlet.multipart.max-file-size=1MB
#默认配置最终都是映射到某个类上,比如这里配置会映射到MultipartProperties
spring.servlet.multipart.max-file-size=10MB
#设置属性k-v
#前面的futn01用于指定/区分不同的绑定对象
furn01.id=100
furn01.name=soft_chair!!
furn01.price=45678.9
  1. 创建quickstart\src\main\java\com\nlc\springboot\bean\Furn.java
@Component
@ConfigurationProperties(prefix = "furn01")
//指定前缀。以 前缀匹配properties 文件的值,将值注入bean
/*** 说明:* 1. Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}* 2. @Data 注解等价使用了 如下注解 @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode*/
//@Data
//说明: @NoArgsConstructor 在编译时,会生成无参构造器, 前面说过,默认情况下,会生成一个无参构造器
//说明:当我们有其它构造器生成时,如果你希望仍然有无参构造器就需要使用@NoArgsConstructor指定一下,否则就会覆盖无参构造器,从而代码错误
@NoArgsConstructor
//说明:@AllArgsConstructor 在编译时,会生成全参构造器
@AllArgsConstructor
//@ToString 在编译时,生成toString, 默认情况下,会生成一个无参构造器
@ToString
//生成所有的set/get方法
@Setter
@Getter
public class Furn {private Integer id;private String name;private Double price;
}
  1. 修改HelloController.java
@Controller
public class HelloController {@RequestMapping("/hello")@ResponseBodypublic String hello(){return "hello, spring boot";}@AutowiredFurn furn;@RequestMapping("/furn")@ResponseBodypublic Furn furn(){return furn;}
}
  1. 启动SpringBoot 主程序,测试

image-20230806115347536

如果测试时发现有结果为空,说明properties 文件的属性写错了。

  1. 配置绑定还有第2 种方式, 也给小伙伴演示下, 完成测试,效果一样, 注意: 注销@Component 需要在BeanConfig.java( 说明: 也可以是其它配置类) 配置@EnableConfigurationProperties(Furn.class), 否则会提示错误

image-20230806115506499

//@EnableConfigurationProperties(Furn.class)解读
//1、开启Furn 配置绑定功能
//2、把Furn 组件自动注册到容器中
@EnableConfigurationProperties(Furn.class)
public class BeanConfig {}

image-20230806115558339

注意事项和细节

1.如果application.properties 有中文, 需要转成unicode 编码写入, 否则出现乱码。可以使用unicode转码工具进行转换。

#设置属性k-v
furn01.id=100
furn01.name=soft_chair\u6c99\u53d1!!
furn01.price=45678.9

2.使用@ConfigurationProperties(prefix = “furn01”) 会提示如下信息, 但是不会影响使用

image-20230806183025605

  1. 解决@ConfigurationProperties(prefix = “furn01”) 提示信息, 在pom.xml 增加依赖, 即可
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

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

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

相关文章

VSCode配置SSH远程免密登录服务器

VScode远程开发时&#xff0c;每次都需要输入密码&#xff0c;其实同理可以和其他应用类似配置免密登录&#xff0c;流程也类似。 1.在本地主机生成公钥和秘钥 ssh-keygen 2.将公钥内容添加至服务器 将生成钥对时会给出其保存路径&#xff0c;找到公钥&#xff0c;复制内容&am…

最小二乘拟合二维直线

目录 1. 原理概述2. python实现3. matlab实现4. C实现 爬虫网站自重。 1. 原理概述 平面直线的表达式为&#xff1a; y k x b (1) ykxb \tag{1} ykxb(1)   假设有 n n n个点 ( x i , y i ) &#xff08; 0 ≤ i < n &#xff09; (x_i, y_i)&#xff08;0≤i<n&…

一起来看看 Compose Accompanist

好久不见&#xff0c;真的挺久了&#xff0c;之前一个月写的文章比现在多半年的都多。今年第一篇文章是简单写了下 Android 14 的适配&#xff1a;Android 14 又来了&#xff1f;别扶&#xff01;抬起我来吧&#xff01; 今天咱们来一起看看 Compose Accompanist 吧&#xff0…

docker菜谱

DockerHub&#xff1a;https://hub.docker.com/ 记录docker常用软件安装&#xff0c;欢迎大家投稿。&#x1f60e;&#x1f60e;&#x1f60e; 文章目录 1. Redis 1. Redis 1、下载redis镜像&#xff1a; docker pull redis:6.2.8 docker pull redis:7.0.02、启动容器&#x…

DAY02_Spring—第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…

sigmoid ReLU 等激活函数总结

sigmoid ReLU sigoid和ReLU对比 1.sigmoid有梯度消失问题&#xff1a;当sigmoid的输出非常接近0或者1时&#xff0c;区域的梯度几乎为0&#xff0c;而ReLU在正区间的梯度总为1。如果Sigmoid没有正确初始化&#xff0c;它可能在正区间得到几乎为0的梯度。使模型无法有效训练。 …

TCP和UDP

目录 TCP和UDP是什么&#xff1f; TCP和UDP有什么区别? 三次握手和四次挥手 TCP维护可靠的通信方式 拥塞控制 滑动窗口的原理 什么是粘包以及粘包的原因 粘包的处理方式 TCP和UDP使用场景 TCP和UDP是什么&#xff1f; TCP&#xff1a; 传输控制协议&#xff08;TCP&am…

HarmonyOS元服务开发实践:桌面卡片字典

一、项目说明 1.DEMO创意为卡片字典。 2.不同卡片显示不同内容&#xff1a;微卡、小卡、中卡、大卡&#xff0c;根据不同卡片特征显示同一个字的不同内容&#xff0c;基于用户习惯可选择喜欢的卡片。 3.万能卡片刷新&#xff1a;用户点击卡片刷新按钮查看新内容&#xff0c;同时…

Java课题笔记~ AspectJ 的开发环境(掌握)

AspectJ 的开发环境(掌握) &#xff08;1&#xff09; maven 依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></depe…

深度学习和OpenCV的对象检测(MobileNet SSD图像识别)

基于深度学习的对象检测时,我们主要分享以下三种主要的对象检测方法: Faster R-CNN(后期会来学习分享)你只看一次(YOLO,最新版本YOLO3,后期我们会分享)单发探测器(SSD,本节介绍,若你的电脑配置比较低,此方法比较适合R-CNN是使用深度学习进行物体检测的训练模型; 然而,…

项目实战 — 消息队列(4){消息持久化}

目录 一、消息存储格式设计 &#x1f345; 1、queue_data.txt&#xff1a;保存消息的内容 &#x1f345; 2、queue_stat.txt&#xff1a;保存消息的统计信息 二、消息序列化 三、自定义异常类 四、创建MessageFileManger类 &#x1f345; 1、约定消息文件所在的目录和文件名…

探索CSS计数器:优雅管理网页元素的计数与序号

113. 探索CSS计数器&#xff1a;优雅管理网页元素的计数与序号 在前端开发中&#xff0c;我们经常需要对网页元素进行计数与序号&#xff0c;如有序列表、表格行号、步骤指示等。为了优雅地管理这些计数与序号&#xff0c;CSS提供了一种强大的功能&#xff1a;CSS计数器&#…

掌握 JVM 调优命令

常用命令 1、jps查看当前 java 进程2、jinfo实时查看和调整 JVM 配置参数3、jstat查看虚拟机统计信息4、jstack查看线程堆栈信息5、jmap查看堆内存的快照信息 JVM 日常调优总结起来就是&#xff1a;首先通过 jps 命令查看当前进程&#xff0c;然后根据 pid 通过 jinfo 命令查看…

MemFire教程|FastAPI+MemFire Cloud+LangChain开发ChatGPT应用-Part2

基本介绍 上篇文章我们讲解了使用FastAPIMemFire CloudLangChain进行GPT知识库开发的基本原理和关键路径的代码实现。目前完整的实现代码已经上传到了github&#xff0c;感兴趣的可以自己玩一下&#xff1a; https://github.com/MemFire-Cloud/memfirecloud-qa 目前代码主要…

ffmpeg源码编译成功,但是引用生成的静态库(.a)报错,报错位置在xxx_list.c,报错信息为某变量未定义

背景&#xff1a;本文是对上一个文章的补充&#xff0c;在源码编译之前&#xff0c;项目是有完整的ffmpeg编译脚本的&#xff0c;只不过新增了断点调试ffmpeg&#xff0c;所以产生的上面的文章&#xff0c;也就是说&#xff0c;我在用make编译成功后&#xff0c;再去做的源码编…

Jenkins+Nginx+vue

安装nodejs 在这里插入图片描述 echo off xcopy C:\ProgramData\Jenkins\.jenkins\workspace\super_manage_vue\dist F:\java\www\super_manage_vue\ /s /e /y echo 复制文件完成 exit安装niginx 配置文件如下 #user nobody; worker_processes 1;#error_log logs/error.lo…

4、长度最小的子数组

找到一个数组中&#xff0c;有多少个连续元素的和小于某个值&#xff0c;求出连续元素的长度的最小值。 滑动窗口法&#xff1a; 其本质也是快慢指针&#xff0c;一个指针指向窗口的起始位置&#xff0c;另一个指针指向窗口的终止位置。 1.定义快慢指针&#xff1a; 2.更新慢指…

排序算法(二)

1.希尔排序-Shell Sort 1.算法原理 将未排序序列按照增量gap的不同分割为若干个子序列&#xff0c;然后分别进行插入排序&#xff0c;得到若干组排好序的序列&#xff1b; 缩小增量gap&#xff0c;并对分割为的子序列进行插入排序&#xff1b;最后一次的gap1&#xff0c;即整个…

【Linux操作系统】GCC编译与静态库、动态库制作详解

GCC是一款广泛使用的开源编译器&#xff0c;它支持多种编程语言&#xff0c;并且具有强大的编译能力。在软件开发中&#xff0c;我们经常需要将代码编译成可执行文件或者库文件。本文将详细介绍GCC编译过程以及如何制作静态库和动态库。 文章目录 一、GCC编译过程1. 预处理阶段…

打破传统直播,最新数字化升级3DVR全景直播

导语&#xff1a; 近年来&#xff0c;随着科技的不断创新和发展&#xff0c;传媒领域也正经历着一场前所未有的变革。在这个数字化时代&#xff0c;直播已经不再仅仅是在屏幕上看到一些人的视频&#xff0c;而是将观众带入一个真实世界的全新体验。其中&#xff0c;3DVR全景直…