spring loCDI 详解
文章目录
- 一、IoC & DI 基本知识
- 1.1 IoC 的基本概念:
- 1.2 IoC 的优势:
- 1.3 DI 介绍:
- 二、IoC 详解
- 2.1 Spring 容器:
- 2.2 被存储 Bean 的命名约定:
- 2.3 Bean 的存储方式:
- 2.3.1 五大类注解:
- 2.3.1.1 @Controller(控制器存储):
- 2.3.1.2 @Service(服务存储):
- 2.3.1.3 @Repository(仓库存储):
- 2.3.1.4 @Configuration(配置存储):
- 2.3.1.5 @Component(组件存储):
- 2.3.1.6 类注解之间的关系:
- 2.3.2 方法注解(@Bean):
- 2.4 Bean 重命名:
- 2.4.1 五大类注解重命名:
- 2.4.2 方法注解重命名:
- 三、DI 详解(@Autowired)
- 3.1 属性注入:
- 3.2 Setter 注入:
- 3.3 构造方法注入:
- 3.4 三种注入优缺点:
- 3.5 处理一个类多个对象的注入情况:
- 3.5.1 @Primary:
- 3.5.2 @Qualifier:
- 3.5.3 @Resource:
一、IoC & DI 基本知识
使用一句话概括 Spring:
Spring 是包含了众多工具方法的 IoC 容器。
1.1 IoC 的基本概念:
其实 IoC 我们在前面已经使用了,我们在前面讲到,在类上面添加 @RestController 和 @Controller 注解,就是把这个对象交给 Spring 管理,Spring 框架启动时就会加载该类。把对象交给 Spring 管理,就是 IoC 思想。
IoC:Inversion of Control (控制反转),也就是说 Spring 是一个"控制反转"的容器。
控制反转的概念:
控制反转更准确的说是控制权反转。当需要某个对象时,传统开发模式中需要自己通过 new 创建对象,现在不需要再进行创建,把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,DI)就可以。
1.2 IoC 的优势:
资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。
-
资源集中管理,实现资源的可配置和易管理。
-
降低了使用资源双方的依赖程度,也就是我们说的解耦合。
Spring 就是一种 IoC 容器,帮助我们来做了这些资源管理。
1.3 DI 介绍:
DI:Dependency Injection(依赖注入)。
容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称之为依赖注入。
IoC 是一种思想,也是"目标",而思想只是一种指导原则,最终还是要有可行的落地方案,而 DI 就属于具体的实现。所以也可以说,DI 是 IoC 的一种实现。
二、IoC 详解
在 Spring 框架中,Bean 和对象是等价的 。也就是说,下面我们提到的 Bean 其实就是指对象。
2.1 Spring 容器:
这里我们来学习一下如何从 Spring 容器中获取对象。
假设 UserController 对象已经被存储在 Spring 容器中。
我们通过下面的代码即可获取到 UserController 对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserController userController = context.getBean(UserController.class);//使用对象userController.sayHi();}
}
ApplicationContext 翻译过来就是:Spring 上下文。
因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那么就得先得到 Spring 的上下文。
关于 getBean 要传递的参数,下面有详细解释。
- getBean 的详解:
上述代码是根据类型来查找对象。
如果 Spring 容器中,同一个类型存在多个 bean 的话,怎么来获取呢?
ApplicationContext 也提供了其他获取 bean 的方式,ApplicationContext 获取 bean 对象的功能,是父类 BeanFactory 提供的功能。
public interface BeanFactory {//以上省略... // 1. 根据bean名称获取bean Object getBean(String var1) throws BeansException;// 2. 根据bean名称和类型获取bean <T> T getBean(String var1, Class<T> var2) throws BeansException;// 3. 按bean名称和构造函数参数动态创建bean,只适⽤于具有原型(prototype)作⽤域的bean Object getBean(String var1, Object... var2) throws BeansException;// 4. 根据类型获取bean <T> T getBean(Class<T> var1) throws BeansException;// 5. 按bean类型和构造函数参数动态创建bean, 只适⽤于具有原型(prototype)作⽤域的
bean<T> T getBean(Class<T> var1, Object... var2) throws BeansException;//以下省略...
}
常用的是上述1,2,4种,这三种方式,获取到的 bean 是一样的。
其中 1,2 种都涉及到根据名称来获取对象。
bean 的名称是什么呢?
2.2 被存储 Bean 的命名约定:
我们看下官方文档的说明:https://docs.spring.io/spring-framework/reference/core/beans/definition.html#beans-beanname
程序开发人员不需要为 bean 指定名称,如果没有显式的提供名称,Spring 容器将为该 bean 生成唯一
的名称。
Bean 默认名称的具体生成规则如下:
- 五大类注解:
**普通:类名的小驼峰表示法。**例如:类名:UserController,Bean 的名称为:userController。
**如果前两位为大写:类名。**例如:类名:UController,Bean 的名称为:UController。
- 方法注解(@Bean):
**Bean 的名称为方法名。**例如:方法名:getUserInfo,Bean 的名称为:getUserInfo。
上面都是 spring 自动帮助我们生成的,如果觉得不合适,程序员可以自己指定,只要不重复就行。
2.3 Bean 的存储方式:
共有两类注解类型可以实现:
- 类注解:@Controller、@Service、@Repository、@Configuration、@Component。
- 方法注解:@Bean。
2.3.1 五大类注解:
2.3.1.1 @Controller(控制器存储):
使用 @Controller 存储 bean 的代码,如下所示:
import org.springframework.stereotype.Controller;@Controller // 将对象存储到 Spring 中
public class UserController {public void sayHi(){System.out.println("hi,UserController...");}
}
从 Spring 容器中获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserController userController = context.getBean(UserController.class);//使用对象userController.sayHi();}
}
效果如下:
2.3.1.2 @Service(服务存储):
使用 @Service 存储 bean 的代码,如下所示:
@Service
public class UserService {public void sayHi(){System.out.println("hello Service~");}
}
从 Spring 容器中获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserService userService = context.getBean(UserService.class);//使用对象userService.sayHi();}
}
效果如下:
2.3.1.3 @Repository(仓库存储):
使用 @Repository 存储 bean 的代码,如下所示:
@Repository
public class UserRepository {public void sayHi(){System.out.println("Hi,Repository~");}
}
从 Spring 容器中获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserRepository userRepository = context.getBean(UserRepository.class);//使用对象userRepository.sayHi();}
}
效果如下:
2.3.1.4 @Configuration(配置存储):
使用 @Configuration 存储 bean 的代码,如下所示:
@Configuration
public class UserConfiguration {public void sayHi(){System.out.println("hi,UserConfiguration...");}
}
从 Spring 容器中获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserConfiguration userConfiguration = context.getBean(UserConfiguration.class);//使用对象userConfiguration.sayHi();}
}
效果如下:
2.3.1.5 @Component(组件存储):
使用 @Component 存储 bean 的代码,如下所示:
@Component
public class UserComponent {public void sayHi(){System.out.println("hi,UserComponent...");}
}
从 Spring 容器中获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//从 Spring 上下文中获取对象UserComponent userComponent = context.getBean(UserComponent.class);//使用对象userComponent.sayHi();}
}
效果如下:
为什么要这么多类注解?
这个也是和我们前面讲的应用分层是呼应的。让程序员看到类注解之后,就能直接了解当前类的用途。
- @Controller:控制层。接收请求,对请求进行处理,并进行响应。
- @Servie:业务逻辑层。处理具体的业务逻辑。
- @Repository:数据层,也称为持久层。负责数据访问操作。
- @Configuration:配置层。处理项目中的一些配置信息。
- @Component:组件层。实际开发中,如果实在分不清是什么层的,就用 @Component(除了控制层,@Controller 有特殊的含义)。
程序的应用分层,调用流程如下:
2.3.1.6 类注解之间的关系:
查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现:
其实这些注解里面都有一个注解 @Component ,说明它们本身就是属于 @Component 的"子类"。
@Component 是一个元注解,也就是说可以注解其他类注解,如 @Controller,@Service ,@Repository 等。这些注解被称为 @Component 的衍生注解。
@Controller,@Service 和 @Repository 用于更具体的用例(分别在表现层,业务逻辑层,数据层),在开发过程中,如果你要在业务逻辑层使用 @Component 或 @Service,显然 @Service 是更好的选择。比如杯子有喝水杯,刷牙杯等,但是我们更倾向于在日常喝水时使用水杯,洗漱时使用刷牙杯。
2.3.2 方法注解(@Bean):
类注解是添加到某个类上的,但是存在两个问题:
- 使用外部包里的类,没办法添加类注解。
- 一个类,需要多个对象,比如多个数据源。
这种场景,我们就需要使用方法注解 @Bean。
注意:方法注解要配合类注解使用。
在 Spring 框架的设计中,方法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中。
如下代码所示:
@Configuration
public class UserConfig {@Beanpublic UserInfo getUserInfo1(){return new UserInfo(1,"zhangsan");}
}
通过上面这段代码的写法,我们就能获取到外部包里的类。无需在外部包里面加上类注解。
- 同一个类,定义多个对象:
@Configuration
public class UserConfig {@Beanpublic UserInfo getUserInfo1(){return new UserInfo(1,"zhangsan");}@Beanpublic UserInfo getUserInfo2(){return new UserInfo(2,"lisi");}
}
通过 Spring 容器,获取对象。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);//获取对应的对象UserInfo getUserInfo1 = (UserInfo)context.getBean("getUserInfo1");UserInfo getUserInfo2 = (UserInfo) context.getBean("getUserInfo2");//进行打印System.out.println(getUserInfo1);System.out.println(getUserInfo2);}
}
效果如下:
可以看到,@Bean 可以针对同一个类,定义多个对象。
这时如果通过类型来获取 Bean 就会报错,显示这个类没有唯一的 Bean。
2.4 Bean 重命名:
2.4.1 五大类注解重命名:
直接在注解里面加上名字即可,或者加上 value = 名字。
@Repository("u1")
public class UserRepository {public void sayHi(){System.out.println("Hi,Repository~");}
}
获取 Bean。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);UserRepository userRepository = context.getBean("u1", UserRepository.class);userRepository.sayHi();}
}
效果如下:
2.4.2 方法注解重命名:
可以通过设置 name 属性给 Bean 对象进行重命名操作,如下代码所示:
@Configuration
public class UserConfig {@Bean(name = {"h1","h2"})public UserInfo getUserInfo1(){return new UserInfo(1,"zhangsan");}
}
其中 name 可以省略(只有一个参数的情况),如果只有一个名称时{}
,也可以省略。
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);UserInfo userInfo = context.getBean("h1", UserInfo.class);System.out.println(userInfo);}
}
三、DI 详解(@Autowired)
依赖注入是一个过程,是指 IoC 容器在创建 Bean 时,去提供运行时所依赖的资源,而资源指的就是对象。、
关于依赖注入,Spring 也给我们提供了三种方式:
-
属性注入(Field Injection)
-
Setter 注入(Setter Injection)
-
构造方法注入(Constructor Injection)
后续的注入演示代码将采用 Service 类注入到 Controller 类中。为了帮助大家理解,下面先给出 Service 类。
@Service
public class UserService {public void sayHi(){System.out.println("hello Service~");}
}
3.1 属性注入:
属性注入是使用 @Autowired 实现的。
Controller 类的实现代码如下:
@Controller // 将对象存储到 Spring 中
public class UserController {@Autowiredprivate UserService userService;public void sayHi(){System.out.println("hi,UserController...");userService.sayHi();}
}
调用 Controller 中的 sayHi 方法:
@SpringBootApplication
public class Spring20240928iocApplication {public static void main(String[] args) {//获取 Spring 上下文对象ApplicationContext context = SpringApplication.run(Spring20240928iocApplication.class, args);UserController userController = context.getBean(UserController.class);userController.sayHi();}
}
效果如下:
3.2 Setter 注入:
Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候,需要加上 @Autowired 注解,如下代码所示:
@Controller // 将对象存储到 Spring 中
public class UserController {private UserService userService;@Autowiredpublic void setUserService(UserService userService){this.userService = userService;}public void sayHi(){System.out.println("hi,UserController...");userService.sayHi();}
}
由于获取 Bean 的方式和效果是一样的所以 Setter 注入和构造方法注入,就不再赘述。
3.3 构造方法注入:
构造方法注入是在类的构造方法中实现注入,如下代码所示:
@Controller // 将对象存储到 Spring 中
public class UserController {private UserService userService;@Autowiredpublic UserController(UserService userService){this.userService = userService;}public void sayHi(){System.out.println("hi,UserController...");userService.sayHi();}
}
注意:如果类只有一个构造方法,那么 @Autowired 注解可以省略,如果类中有多个构造方法, 那么需要添加上 @Autowired 来明确指定到底使用哪个构造方法。
3.4 三种注入优缺点:
- 属性注入:
优点:简洁,使用方便。
缺点:
-
只能用于 IoC 容器,如果是非 IoC 容器不可用。
-
不能注入一个 Final 修饰的属性。
- Setter注入(Spring 3.X推荐):
优点:方便在类实例之后,重新对该对象进行配置或者注入。
缺点:不能注入一个 Final 修饰的属性。
- 构造函数注入(Spring 4.X推荐):
优点:
- 可以注入 final 修饰的属性。
- 通用性好,构造方法是 JDK 支持的,所以更换任何框架,它都是适用的。
缺点:注入多个对象时,构造方法会写很长。
3.5 处理一个类多个对象的注入情况:
当同一类型存在多个 bean 时,实用 @Autowired 会存在问题。
@Configuration
public class UserConfig {@Beanpublic UserInfo getUserInfo1(){return new UserInfo(1,"zhangsan");}@Beanpublic UserInfo getUserInfo2(){return new UserInfo(2,"lisi");}
}
报错如下:
报错的原因是:非唯一的 Bean 对象。
如何解决上述问题呢?Spring提供了以下几种解决方案:
-
@Primary
-
@Qualifier
-
@Resource
3.5.1 @Primary:
使用 @Primary 注解:当存在多个相同类型的 Bean 注入时,加上 @Primary 注解,来确定默认的实现。
@Configuration
public class UserConfig {@Primary@Beanpublic UserInfo getUserInfo1(){return new UserInfo(1,"zhangsan");}@Beanpublic UserInfo getUserInfo2(){return new UserInfo(2,"lisi");}
}
3.5.2 @Qualifier:
使用 @Qualifier 注解:指定当前要注入的 bean 。在 @Qualifier 的 value 属性中,指定注入 bean 的名称。
注意:@Qualifier 注解不能单独使用,必须配合 @Autowired 使用。
@Controller // 将对象存储到 Spring 中
public class UserController {@Qualifier("getUserInfo2")@Autowiredprivate UserInfo userInfo;public void printUserInfo(){System.out.println(userInfo);}
}
3.5.3 @Resource:
使用 @Resource 注解:是按照 bean 的名称进行注入。通过 name 属性指定要注入的 bean 的名称。
@Controller // 将对象存储到 Spring 中
public class UserController {@Resource(name = "getUserInfo1")private UserInfo userInfo;public void printUserInfo(){System.out.println(userInfo);}
}
常见面试题:@Autowird 与 @Resource 的区别:
- @Autowired 是 spring 框架提供的注解,而 @Resource 是 JDK 提供的注解。
- @Autowired 默认是按照类型注入,而 @Resource 是按照名称注入。相比于 @Autowired 来说,@Resource 支持更多的参数设置。
使用习惯:
如果一个类的 Bean 只有一个的话,使用 @Autowired。
如果一个类的 Bean 有多个的话,使用 @Resource。
结语:
其实写博客不仅仅是为了教大家,同时这也有利于我巩固知识点,和做一个学习的总结,由于作者水平有限,对文章有任何问题还请指出,非常感谢。如果大家有所收获的话,还请不要吝啬你们的点赞收藏和关注,这可以激励我写出更加优秀的文章。
相关文章:
spring loCDI 详解
文章目录 一、IoC & DI 基本知识1.1 IoC 的基本概念:1.2 IoC 的优势:1.3 DI 介绍: 二、IoC 详解2.1 Spring 容器:2.2 被存储 Bean 的命名约定:2.3 Bean 的存储方式:2.3.1 五大类注解:2.3.1.…...
遇到 Docker 镜像拉取失败的问题时该如何解决
遇到 Docker 镜像拉取失败的问题时,可以按照以下步骤进行排查和解决: 1. 检查网络连接 确保你的计算机可以访问互联网。尝试 ping 通 Docker Hub 或其他镜像仓库的域名: ping hub.docker.com2. 检查 Docker 服务状态 确保 Docker 服务正在…...
【C/C++】错题记录(三)
题目一 题目二 题目三 题目四 题目五 题目六 题目七??? 题目八 这道题主要考查对数据类型和位运算的理解与运用。 分析选项 A: *((unsigned char *)(&number) 1)0xcd; 这里将 number 的地址强制转换为 unsigned char* 类型&a…...
深入理解Web浏览器与服务器的连接过程
目录 1. 域名解析:找到地址 2. TCP连接:建立通信 3. HTTP请求:点菜 4. 服务器处理请求:厨房做菜 5. HTTP响应:上菜 6. 客户端接收响应:品尝美食 7. 关闭TCP连接:吃完离开 8. 持久连接&a…...
深入解析 https
我的主页:2的n次方_ 1. 背景介绍 在使用 http 协议的时候是不安全的,可能会出现运营商劫持等安全问题,运营商通过劫持 http 流量,篡改返回的网页内容,例如广告业务,可能会通过 Referer 字段 来统计是…...
NP-hard问题
一、前置知识 1.多项式 多项式是由变量(如x、y等)和系数通过有限次的加、减、乘运算得到的表达式。例如3x^22x 1就是一个关于(x)的多项式 2.时间复杂度 时间复杂度是用来衡量算法运行效率的一个指标。它描述了算法运行时间随着输入规模增长而增长的量…...
【Nacos架构 原理】内核设计之Nacos通信通道
文章目录 Nacos通信通道 (长链接)现状背景场景分析配置服务 长链接核心诉求功能性诉求负载均衡连接生命周期 Nacos通信通道 (长链接) 现状背景 Nacos 1.X 版本 Config/Naming 模块各自的推送通道都是按照自己的设计模型来实现的…...
【单片机】单片机map表详细解析
1、RO Size、RW Size、ROM Size分别是什么 首先将map文件翻到最下面,可以看到 1.1 RO Size:只读段 Code:程序的代码部分(也就是 .text 段),它存放了程序的指令和可执行代码。 RO Data:只读…...
考研笔记之操作系统(三)- 存储管理
操作系统(三)- 存储管理 1. 内存的基础知识1.1 存储单元与内存地址1.2 按字节编址和按字编址1.3 指令1.4 物理地址和逻辑地址1.5 从写程序到程序运行1.6 链接1.6.1 静态链接1.6.2 装入时动态链接1.6.3 运行时动态链接 1.7 装入1.7.1 概念1.7.2 绝对装入1…...
vim/vi常用命令大全
启动和退出Vim 命令/操作作用vim启动Vimvim filename直接打开指定的文件命令模式下,输入 :q退出,q!强制退出:wq保存并退出:wq!保存并强制退出vim中按下a进入编辑模式Esc退出编辑模式进入命令模式new创建新窗口close关闭窗口 光标移动 命令/操作作用h、…...
什么是大语言模型,一句话解释
定义 先说语言模型(Language Model)旨在建模词汇序列的生成概率,提升机器的语言智能水平,使机 器能够模拟人类说话、写作的模式进行自动文本输出。 白话:语言模式是一种解决机器与人类交流的手段,机器人与…...
【数据库】 MongoDB 撤销用户的角色和权限
在 MongoDB 中,撤销用户的角色和权限是一项重要的管理任务,确保用户仅能访问和操作他们需要的数据。以下是如何撤销用户的角色和权限的详细步骤。 1. 使用 MongoDB Shell 撤销角色 1.1 修改用户角色 要撤销用户的角色,可以使用 updateUser…...
vue2接入高德地图实现折线绘制、起始点标记和轨迹打点的完整功能(提供Gitee源码)
目录 一、申请密钥 二、安装element-ui 三、安装高德地图依赖 四、完整代码 五、运行截图 六、官方文档 七、Gitee源码 一、申请密钥 登录高德开放平台,点击我的应用,先添加新应用,然后再添加Key。 如图所示填写对应的信息&…...
【重学 MySQL】四十六、创建表的方式
【重学 MySQL】四十六、创建表的方式 使用CREATE TABLE语句创建表使用CREATE TABLE LIKE语句创建表使用CREATE TABLE AS SELECT语句创建表使用CREATE TABLE SELECT语句创建表并从另一个表中选取数据(与CREATE TABLE AS SELECT类似)使用CREATE TEMPORARY …...
WPS在表格中填写材料时,内容过多导致表格不换页,其余内容无法正常显示 以及 内容过多,导致表格换页——解决方法
一、现象 1,内容过多导致表格不换页,其余内容无法正常显示 2,内容过多,导致表格换页 二、解决方法 在表格内右击,选择表格属性 在菜单栏选择行,勾选允许跨页断行,点击确定即可 1࿰…...
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-01目录1. Beyond Text-to-Text: An Overview of Multimodal and Generative Artificial Intelligence for Education Using Topi…...
第一弹:C++ 的基本知识概述
文章目录 知识点 1:C 的概述1. C的特征2. C 程序的编辑、编译和执行3. 第一个 C 源程序4. 面向对象程序设计思想4.1 面向对象程序设计思想初始4.2 面向对象程序设计思想的核心 知识点 2:C 对 C 的扩展1. 作用域访问运算符 ::1.1 全局变量和局部变量1.2 作…...
在职场,没人告诉你的人情世故
职场中,想要过得游刃有余,就必须懂一些人情世故和处事原则。今天,给大家分享个人认为非常重要的5点人情世故,希望能帮你在职场里少吃点亏、多份从容。 01 不要空口道谢 在职场中,别人帮了你,口头道谢是基…...
激光切割机适用材质有哪些
激光切割机是一种利用激光束对各种材料进行高精度、高速度切割的机器设备。其适用材质广泛,包括但不限于以下两大类: 一、金属材料 不锈钢:激光切割机较容易切割不锈钢薄板,使用高功率YAG激光切割系统,切割不锈钢板的…...
C#自定义工具类-数组工具类
目录 数组工具类基本操作 1.排序:升序,降序 2.查找 1)查找最值:最大值,最小值 2)查找满足条件的单个对象 3)查找满足条件的所有对象 4)选取数组中所有对象的某一字段 完整代…...
18年408数据结构
第一题: 解析:这道题很简单,按部就班的做就可以了。 画出S1,S2两个栈的情况: 第一轮: S1: S2: 2 3 - 8 * 5 从S1中依次弹…...
Android 通过自定义注解实现Activity间跳转时登录路由的自动拦截
应用场景 在Android 中部分软件需要登录才能使用,但是有的页面又不需要登录,Android不同于Web可以直接拦截重定向路由,因此如果在Android中如果需要检测是否登录,如果没登录跳转登录的话就需要再每个页面中判断,当然也…...
安全开发指南
1. 准备工作与培训 安全文化与意识:建立并强化组织的安全文化,对所有成员进行安全意识培训。安全策略与标准:制定明确的安全开发策略、标准和流程,包括代码审查、安全测试、事件响应等。工具与技术选择:选择合适的开发…...
【word脚注】双栏设置word脚注,脚注仅位于左栏,右栏不留白
【word脚注】双栏设置word脚注,脚注仅位于左栏,右栏不留白 调整前效果解决方法调整后效果参考文献 调整前效果 调整前:脚注位于左下角,但右栏与左栏内容对其,未填充右下角的空白区域 解决方法 备份源文件复制脚注内…...
ROS学习笔记(三):VSCode集成开发环境快速安装,以及常用扩展插件配置
文章目录 前言VSCode集成开发环境1 安装VSCode2 VSCode扩展插件2.1 VSCode扩展插件模块介绍2.1 常用扩展插件配置一、语言支持类插件二、智能辅助类插件三、科学计算与数据分析类插件四、ROS开发相关插件 3 总结相关链接 前言 关于Ubuntu与ROS的常规安装,可以看这几…...
论文精读--Two-Stream Convolutional Networks for Action Recognition in Videos
对于单张图片,丢进卷积和全连接层直接得出分类结果就行 但对于视频,早期的一些工作把视频中的一些关键帧抽取出来,把一个个帧通过网络,最后把结果合并,或者把帧叠起来,一起丢进网络。在网络中进行early fu…...
JAVA姓氏头像情侣头像家庭头像签名头像谐音顽埂头像设计小程序头像大全系统小程序源码
姓氏头像到谐音梗,打造你的专属头像大全系统 🎨✨ 👨👩👧👦 家庭头像:记录温馨瞬间 在这个充满爱的时代,用一张家庭头像来记录你和家人的美好瞬间吧!我们的“姓氏…...
UE5.4.3 Replay 重播回放系统
工程的配置文件DefaultEngine.ini中需要加入 +NetDriverDefinitions=(DefName=“DemoNetDriver”,DriverClassName=“/Script/Engine.DemoNetDriver”,DriverClassNameFallback=“/Script/Engine.DemoNetDriver”) 此步骤将启用并加载DemoNetDriver .ini添加示例 [/Script/En…...
深入掌握 Protobuf 与 RPC 的高效结合:实现C++工程中的高效通信
目录 一、Protobuf与RPC框架的通信流程概述二、Protobuf与RPC在C中的实际应用2.1 定义 .proto 文件2.2 编译 .proto 文件生成C代码2.3 实现服务器端逻辑2.4 实现客户端逻辑2.5 使用CMake构建工程2.6 编译与运行2.7 关键组件解析2.8 序列化与反序列化的实现 三、关键实现与解析四…...
录屏软件大比拼:四款必备工具助你轻松录制精彩瞬间!
哎呀,说到电脑录屏这事儿,我这个办公室小文员可是深有体会啊!平时工作里,经常需要录个会议啊、做个教程啊,或者分享个操作技巧给同事们看。市面上的录屏软件多得数不清,但我最常用的几款工具。今天就来跟大…...
建筑招聘网官网/一键优化是什么意思
环境:tomcat7.0 java1.8 项目框架:zk 系统:centos最近出现了一个很奇怪的问题,通过ip访问项目可以上传文件,但是通过域名访问项目就不可以上传。首先对项目进行一些排查,看看是哪里的问题。下面是我进行的排…...
可以完成交易的网站 做/公司推广方案
4、常见函数的解读 Thread类的方法: sleep(long millis):让当前正在执行的线程休息多久,暂时让出cpu给其他线程执行,但是不会释放它所占有的对象锁。join():一个正在执行的线程调用了另外一个线程的join方法…...
手机建设银行网站进不去/免费发布产品信息的网站
Java语言基本语法 一、标识符和关键字 标识符 在java语言中,用来标志类名、对象名、变量名、方法名、类型名、数组名、包名的有效字符序列,称为“标识符”;标识符由字母、数字、下划线、美元符号组成,且第一个字符不能是数字&…...
开源 网站源代码/北京it培训机构哪家好
点击上方 "Java指南者"关注, 星标或置顶一起成长免费送 1024GB 精品学习资源 来源:https://juejin.im/post/6881259928909152270什么是方法引用?对一个类某个方法进行引用。形式大致为:类型::方法名(构造方法为类型::new)对象::方法名例子&…...
为什么做网站结构优化/泉州seo培训
我将整理文章分享数据工作中的经验,因为业务内容上的差异,可能导致大家的理解不一致,无法体会到场景中的诸多特殊性,不过相信不断的沟通和交流,可以解决很多问题。前面我们分析了职场基本功、数据指标体系,…...
网站头部图片如何做/电子商务网站建设案例
众所周知,类的对象会随着程序的终止而被垃圾收集器销毁。如果要在不重新创建对象的情况下调用该类,该怎么做?这就可以通过序列化将数据转换为字节流。 对象序列化是一个用于将对象状态转换为字节流的过程,可以将其保存到磁盘文件中…...