【精选】SpringDI依赖注入及注解实现SpringIoC

news2024/12/28 5:10:22

SpringDI

请添加图片描述

什么是依赖注入

在这里插入图片描述

依赖注入(Dependency Injection,简称DI),它是Spring控制反转思想的具体实现。

控制反转将对象的创建交给了Spring,但是对象中可能会依赖其他对象。比如service类中要有dao类的属性,我们称service依赖于dao。之前需要手动注入属性值,代码如下:

public interface StudentDao {
  Student findById(int id);
}


public class StudentDaoImpl implements StudentDao{
  @Override
  public Student findById(int id) {
    // 模拟根据id查询学生
    return new Student(1,"张三","北京");
   }
}


public class StudentService {
  // service依赖dao,手动注入属性值,即手动维护依赖关系
  private StudentDao studentDao = new StudentDaoImpl();


  public Student findStudentById(int id){
    return studentDao.findById(id);
   }
}

此时,当StudentService的想要使用StudentDao的另一个实现类如StudentDaoImpl2时,则需要修改Java源码,造成代码的可维护性降低。

而使用Spring框架后,Spring管理Service对象与Dao对象,此时它能够为Service对象注入依赖的Dao属性值。这就是Spring的依赖注入。简单来说,控制反转是创建对象,依赖注入是为对象的属性赋值。

依赖注入方式

在这里插入图片描述

在之前开发中,可以通过setter方法或构造方法设置对象属性值:

// setter方法设置属性
StudentService studentService = new StudentService();
StudentDao studentDao = new StudentDao();
studentService.setStudentDao(studentDao);


// 构造方法设置属性
StudentDao studentDao = new StudentDao();
StudentService studentService = new StudentService(studentDao);

Spring可以通过调用setter方法或构造方法给属性赋值

Setter注入
  1. 被注入类编写属性的setter方法

    public class StudentService {
      private StudentDao studentDao;
      public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
       }
    }
    
  2. 配置文件中,给需要注入属性值的<bean>中设置<property>

    <bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>
    <bean id="studentService" class="com.Spring.service.StudentService">
      <!--依赖注入-->
      <!--name:对象的属性名 ref:容器中对象的id值-->
      <property name="studentDao" ref="studentDao"></property>
    </bean>
    
  3. 测试是否注入成功

    @Test
    public void t2(){
      ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      StudentService studentService = (StudentService) ac.getBean("studentService");
      System.out.println(studentService.findStudentById(1));
    }
    
构造方法注入
  1. 被注入类编写有参的构造方法

    public class StudentService {
      private StudentDao studentDao;
      public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;
       }
    }
    
  2. 给需要注入属性值的<bean>中设置<constructor-arg>

    <bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>
    
    
    <bean id="studentService" class="com.Spring.service.StudentService">
      <!-- 依赖注入 -->
      <!-- name:对象的属性名  ref:配置文件中注入对象的id值 -->
      <constructor-arg name="studentDao" ref="studentDao"></constructor-arg>
    </bean>
    
  3. 测试是否注入成功

    @Test
    public void t2(){
      ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      StudentService studentService = (StudentService) ac.getBean("studentService");
      System.out.println(studentService.findStudentById(1));
    }
    
自动注入

自动注入不需要在<bean>标签中添加其他标签注入属性值,而是自动从容器中找到相应的bean对象设置为属性值。

自动注入有两种配置方式:

  • 全局配置:在<beans>中设置default-autowire属性可以定义所有bean对象的自动注入策略。
  • 局部配置:在<bean>中设置autowire属性可以定义当前bean对象的自动注入策略。

autowire的取值如下:

  • no:不会进行自动注入。
  • default:全局配置default相当于no,局部配置default表示使用全局配置
  • byName:在Spring容器中查找id与属性名相同的bean,并进行注入。需要提供set方法。
  • byType:在Spring容器中查找类型与属性类型相同的bean,并进行注入。需要提供set方法。
  • constructor:在Spring容器中查找id与属性名相同的bean,并进行注入。需要提供构造方法。

测试自动注入:

  1. 为依赖的对象提供setter和构造方法:

    public class StudentService {
      // 依赖
      private StudentDao studentDao;
        
      // 构造方法
      public StudentService() {
       }
        
      public StudentService(StudentDao studentDao) {
        this.studentDao = studentDao;
       }
        
      // setter方法
      public void setStudentDao(StudentDao studentDao) {
        this.studentDao = studentDao;
       }
        
      // 调用依赖的方法
      public Student findStudentById(int id) {
        return studentDao.findById(id);
       }
    }
    
    
  2. 配置自动注入:

    <!-- 根据beanId等于属性名自动注入 -->
    <bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>
    <bean id="studentService" class="com.Spring.service.StudentService" autowire="byName"></bean>
    
    
    <!-- 根据bean类型等于属性类型自动注入 -->
    <bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>
    <bean id="studentService" class="com.Spring.service.StudentService" autowire="byType"></bean>
    
    
    <!-- 利用构造方法自动注入 -->
    <bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>
    <bean id="studentService" class="com.Spring.service.StudentService" autowire="constructor"></bean>
    
    <!-- 配置全局自动注入 -->
    <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"
        default-autowire="constructor">
    
    

依赖注入类型

DI支持注入bean类型、基本数据类型和字符串、List集合、Set集合、Map集合、Properties对象类型等,他们的写法如下:

  1. 准备注入属性的类

    public class StudentService {
      private StudentDao studentDao; // bean属性
      private String name; //字符串类型
      private int count; //基本数据类型
      private List<String> names; // 字符串类型List集合
      private List<Student> students1; // 对象类型List集合
      private Set<Student> students2; // 对象类型Set集合
      private Map<String,String> names2; // 字符串类型Map集合
      private Map<String,Student> students3; // 对象类型Map集合
      private Properties properties; //Properties类型
      
      // 省略getter/setter/toString
    }
    
    
  2. 准备测试方法

    @Test
    public void t3(){
      ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      StudentService studentService = (StudentService) ac.getBean("studentService");
      System.out.println(studentService);
    }
    
    
注入bean类型

写法一:

<bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>


<bean id="studentService" class="com.Spring.service.StudentService">
  <property name="studentDao" ref="studentDao"></property>
</bean>

写法二:

<bean id="studentDao" class="com.Spring.dao.StudentDaoImpl"></bean>


<bean id="studentService" class="com.Spring.service.StudentService">
  <property name="studentDao" >
    <ref bean="studentDao"></ref>
  </property>
</bean>

注入基本数据类型和字符串类型
<bean id="studentService" class="com.Spring.service.StudentService">
  <!--  写法一 name:属性名  value:属性值-->
  <property name="name" value="李四"></property>


  <!--  写法二 name:属性名  value:属性值-->
  <property name="count">
    <value>10</value>
  </property>
</bean>

注入List集合
<bean id="studentService" class="com.Spring.service.StudentService">
  <!-- 简单数据类型List集合 name:属性名 -->
  <property name="names">
    <list>
      <value>Spring</value>
      <value>张三</value>
    </list>
  </property>


  <!-- 对象类型List集合 name:属性名 -->
  <property name="students1">
    <list>
      <bean class="com.Spring.domain.Student">
        <property name="id" value="1"/>
        <property name="name" value="Spring"/>
        <property name="address" value="北京"/>
      </bean>
      <bean class="com.Spring.domain.Student">
        <property name="id" value="2"/>
        <property name="name" value="李四"/>
        <property name="address" value="北京"/>
      </bean>
    </list>
  </property>
</bean>

注入Set集合
<bean id="studentService" class="com.Spring.service.StudentService">
  <!-- Set集合 -->
  <property name="students2">
    <set>
      <bean class="com.Spring.domain.Student">
        <property name="id" value="1"/>
        <property name="name" value="Spring"/>
        <property name="address" value="北京"/>
      </bean>
      <bean class="com.Spring.domain.Student">
        <property name="id" value="2"/>
        <property name="name" value="李四"/>
        <property name="address" value="北京"/>
      </bean>
    </set>
  </property>
</bean>

注入Map集合

简单数据类型Map集合:

<bean id="studentService" class="com.Spring.service.StudentService">
  <property name="names2">
    <map>
      <entry key="student1" value="李四"/>
      <entry key="student2" value="张三"/>
    </map>
  </property>
</bean>

对象类型Map集合:

<bean id="studentService" class="com.Spring.service.StudentService">
  <property name="students3">
    <map>
      <entry key="student1" value-ref="s1"/>
      <entry key="student2" value-ref="s2"/>
    </map>
  </property>
</bean>


<bean id="s1" class="com.Spring.domain.Student">
  <property name="id" value="1"/>
  <property name="name" value="Spring"/>
  <property name="address" value="北京"/>
</bean>
<bean id="s2" class="com.Spring.domain.Student">
  <property name="id" value="2"/>
  <property name="name" value="李四"/>
  <property name="address" value="北京"/>
</bean>

注入Properties对象
<bean id="studentService" class="com.Spring.service.StudentService">
  <property name="properties">
    <props>
      <prop key="配置1">值1</prop>
      <prop key="配置2">值2</prop>
    </props>
  </property>
</bean>

注解实现IOC

准备工作

注解配置和xml配置对于Spring的IOC要实现的功能都是一样的,只是配置的形式不一样。

准备工作

  1. 创建一个新的Spring项目。

  2. 编写pojo,dao,service类。

  3. 编写空的配置文件,如果想让该文件支持注解,需要添加新的约束

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        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
                  http://www.springframework.org/schema/context
                  http://www.springframework.org/schema/context/spring-context.xsd">
    
    
    </beans>
    
    

@Component

作用:用于创建对象,放入Spring容器,相当于<bean id="" class="">

位置:类上方

注意:

  • 要在配置文件中配置扫描的包,扫描到该注解才能生效。

    <context:component-scan base-package="com.Spring"></context:component-scan>
    
  • @Component注解配置bean的默认id是首字母小写的类名。也可以手动设置bean的id值。

    // 此时bean的id为studentDaoImpl
    @Component
    public class StudentDaoImpl implements StudentDao{
      public Student findById(int id) {
        // 模拟根据id查询学生
        return new Student(1,"张三","北京");
       }
    }
    

    // 此时bean的id为studentDao
    @Component(“studentDao”)
    public class StudentDaoImpl implements StudentDao{
    public Student findById(int id) {
    // 模拟根据id查询学生
    return new Student(1,“张三”,“北京”);
    }
    }

    
    

@Repository、@Service、@Controller

作用:这三个注解和@Component的作用一样,使用它们是为了区分该类属于什么层。

位置:

  • @Repository用于Dao层
  • @Service用于Service层
  • @Controller用于Controller层
@Repository
public class StudentDaoImpl implements StudentDao{}


@Service
public class StudentService {}

@Scope

作用:指定bean的创建策略

位置:类上方

取值:singleton prototype request session globalsession

@Service
@Scope("singleton")
public class StudentService {}

@Autowired

作用:从容器中查找符合属性类型的对象自动注入属性中。用于代替<bean>中的依赖注入配置。

位置:属性上方、setter方法上方、构造方法上方。

注意:

  1. @Autowired写在属性上方进行依赖注入时,可以省略setter方法。

    @Component
    public class StudentService {
      @Autowired
      private StudentDao studentDao;
      public Student findStudentById(int id){
        return studentDao.findById(id);
       }
    }
    
    
    @Test
    public void t2(){
      ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
      StudentService studentService = (StudentService) ac.getBean("studentService");
      System.out.println(studentService.findStudentById(1));
    }
    
  2. 容器中没有对应类型的对象会报错

    // 如果StudentDaoImpl没有放到容器中会报错
    //@Component("studentDao")
    public class StudentDaoImpl implements StudentDao{
      public Student findById(int id) {
        // 模拟根据id查询学生
        return new Student(1,"张三","北京");
       }
    }
    
  3. 容器中有多个对象匹配类型时,会找beanId等于属性名的对象,找不到会报错。

    // 如果容器中都多个同类型对象,会根据id值等于属性名找对象
    @Component("studentDao")
    public class StudentDaoImpl implements StudentDao{
      public Student findById(int id) {
        // 模拟根据id查询学生
        return new Student(1,"张三","北京");
       }
    }
    
    
    @Component
    public class StudentDaoImpl2 implements StudentDao{
      public Student findById(int id) {
        // 模拟根据id查询学生
        return new Student(1,"张三","北京");
       }
    }
    

@Qualifier

作用:在按照类型注入对象的基础上,再按照bean的id注入。

位置:属性上方

注意:@Qualifier必须和@Autowired一起使用。

@Component
public class StudentService {
  @Autowired
  @Qualifier("studentDaoImpl2")
  private StudentDao studentDao;
  public Student findStudentById(int id){
    return studentDao.findById(id);
   }
}

@Value

作用:注入String类型和基本数据类型的属性值。

位置:属性上方

用法:

  1. 直接设置固定的属性值

    @Service
    public class StudentService {
      @Value("1")
      private int count;
    
    
      @Value("hello")
      private String str;
    }
    
    
  2. 获取配置文件中的属性值:

    1. 编写配置文件db.properties

      jdbc.username=root
      jdbc.password=123456
      
    2. spring核心配置文件扫描配置文件

      <context:property-placeholder location="db.properties"></context:property-placeholder>
      
    3. 注入配置文件中的属性值

      @Value("${jdbc.username}")
      private String username;
      
      
      @Value("${jdbc.password}")
      private String password;
      

@Configuration

此时基于注解的IOC配置已经完成,但是我们依然离不开Spring的xml配置文件。接下来我们脱离bean.xml,使用纯注解实现IOC。

在真实开发中,我们一般还是会保留xml配置文件,很多情况下使用配置文件更加方便。

纯注解实现IOC需要一个==Java类代替xml文件。==这个Java类上方需要添加@Configuration,表示该类是一个配置类,作用是代替配置文件。

@Configuration
public class SpringConfig {  
}

@ComponentScan

作用:指定spring在初始化容器时扫描的包。

位置:配置类上方

@Configuration
@ComponentScan("com.Spring")
public class SpringConfig {
}

@PropertySource

作用:代替配置文件中的<context:property-placeholder>扫描配置文件

位置:配置类上方

注意:配置文件位置前要加关键字classpath

@Configuration
@PropertySource("classpath:db.properties")
public class JdbcConfig {
  @Value("${jdbc.username}")
  private String username;


  @Value("${jdbc.password}")
  private String password;

}

@Bean

作用:将方法的返回值对象放入Spring容器中。如果想将第三方类的对象放入容器,可以使用@Bean

位置:配置类的==方法==上方。

属性:name:给bean对象设置id

注意:@Bean修饰的方法如果有参数,spring会根据参数类型从容器中查找可用对象。

举例:如果想将jdbc连接对象放入Spring容器,我们无法修改Connection源码添加@Component,此时就需要使用将@Bean该对象放入Spring容器

  1. 添加驱动依赖

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</version>
    </dependency>
    
  2. 将Connection对象放入Spring容器

    @Bean(name = "connection")
    public Connection getConnection(){
      try {
        Class.forName("com.mysql.cj.jdbc.Driver");
        return DriverManager.getConnection("jdbc:mysql:///mysql", "root", "root");
       } catch (Exception exception) {
        return null;
       }
    }
    
  3. 测试

    @Test
    public void t5(){
      ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfig.class);
      Connection connection = (Connection) ac.getBean("connection");
      System.out.println(connection);
    }
    

@Import

作用:如果配置过多,会有多个配置类,该注解可以为主配置类导入其他配置类

位置:主配置类上方

// Jdbc配置类
@Configuration
public class JdbcConfig {
  @Bean(name = "connection")
  public Connection getConnection(){
    try {
      Class.forName("com.mysql.cj.jdbc.Driver");
      return DriverManager.getConnection("jdbc:mysql:///mysql", "root", "root");
     } catch (Exception exception) {
      return null;
     }
   }
}

// 主配置类
@Configuration
@ComponentScan("com.Spring")
@Import(JdbcConfig.class)
public class SpringConfig {
}

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

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

相关文章

什么是量子优势?

量子优势是量子计算领域正在积极努力的里程碑&#xff0c;量子计算机可以解决最强大的非量子或经典计算机无法解决的问题。 量子是指原子和分子的尺度&#xff0c;在这个尺度上&#xff0c;我们所经历的物理定律被打破&#xff0c;并且应用了一组不同的、违反直觉的定律。量子…

JS之Object.defineProperty方法

给对象添加属性的方法有许多&#xff0c;这次让我为大家介绍一种给对象添加属性的静态方法吧&#xff01; 语法&#xff1a;Objcet.defineProperty(对象的名称&#xff0c;“添加的键名”&#xff0c;{value&#xff1a;键值}) const obj {name:"张三",age:18}// 我…

一则 MongoDB 副本集迁移实操案例

文中详细阐述了通过全量 增量 Oplog 的迁移方式&#xff0c;完成一套副本集 MongoDB 迁移的全过程。 作者&#xff1a;张然&#xff0c;DBA 数据库技术爱好者~ 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。 本文约 900…

【Linux下基本指令——(1)】

Linux下基本指令——&#xff08;1&#xff09; 一. ls 指令1.1.语法&#xff1a;1.2.功能&#xff1a;1.3.常用选项&#xff1a;1.4.举例&#xff1a;1.5.Xshell7展示 二. pwd 命令2.1.语法: 2.2.功能&#xff1a;2.3.常用选项&#xff1a;2.4.Xshell7展示 三. cd 指令3.1.语法…

MySql的InnoDB的三层B+树可以存储两千万左右条数据的计算逻辑

原创/朱季谦 B树是一种在非叶子节点存放排序好的索引而在叶子节点存放数据的数据结构&#xff0c;值得注意的是&#xff0c;在叶子节点中&#xff0c;存储的并非只是一行表数据&#xff0c;而是以页为单位存储&#xff0c;一个页可以包含多行表记录。非叶子节点存放的是索引键…

基于单片机的智能饮水机控制系统(论文+源码)

1. 系统设计 本次智能饮水机控制系统的设计研究一款以STC89C52单片机为核心的智能饮水机控制系统&#xff0c;其主要功能设计如下&#xff1a; 1.该饮水机利用DS18B20数字温度传感器实时采集饮水机内水的温度&#xff0c;其检测温度范围为0-100℃&#xff0c;精度0.1℃&#…

rabbitMQ对优先级队列的使用

注意事项&#xff1a; 1.队列设置优先级 权制范围&#xff08;0-255&#xff09;推荐0-10 否则浪费CPU与内存 2.发消息时给消息设置优先级 3.消息需要完全事先在队列中&#xff0c;在被消费者消费 会被排序&#xff0c;否则边生产边消费不会达到预期的队列优先效果。 优先级队列…

web框架,django,路由控制,视图层(补充)

web框架 是什么&#xff1f; web 框架是什么---》别人帮咱们写了一些基础代码---》我们只需要在固定的位置写固定的代码--》就能实现一个web应用 Web框架&#xff08;Web framework&#xff09;是一种开发框架&#xff0c;用来支持动态网站、网络应用和网络服务的开发。这大多…

NX二次开发UF_MTX3_x_vec 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_MTX3_x_vec Defined in: uf_mtx.h void UF_MTX3_x_vec(const double mtx [ 9 ] , double x_vec [ 3 ] ) overview 概述 Returns the X-direction vector of a matrix. 返回矩阵…

初次尝试http OAuth2验证的请求

第一次对接OAuth2验证的接口&#xff0c; 莫不着门道&#xff0c;后面获取token成功后&#xff0c;发现其实不难&#xff0c; 用postman举例&#xff1a; 其实挺简单。用客户端id秘钥 获取token---》后面的请求带上token 1,在head中增加 Authorization头 内容格式如上图&…

除自身以外数组的乘积——力扣算法

题目 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时…

Dubbo框架(一)

1&#xff1a;简介 Dubbo 是阿里巴巴公司开源的一个Java高性能优秀的服务框架 Apache Dubbo 是一款 RPC 服务开发框架&#xff0c;用于解决微服务架构下的服务治理与通信问题 这是Dubbo官网的介绍&#xff0c;下面是我对这dubbo的理解 首先介绍下什么是RPC&#xff1a; 常…

【JavaScript】实现页面中填写文档、电子签名,填写完后 转为pdf并自动下载;附带psd转图片预览效果

效果图&#xff1a; 需求&#xff1a; 用户可以在线进行文档编辑&#xff0c;在线电子签名&#xff0c;然后点击可以另存为pdf文档 实现&#xff1a; 首先实现布局 让填写文档 随着页面的变化 一直保持居中 <!DOCTYPE html> <html lang"en"><head…

YOLOv8自用训练教程——训练、测试、推理

前言 继YOLOv5大成之后&#xff0c;原作者U神又开源了更强的YOLOv8&#xff0c;说是论文在写&#xff0c;不知道这次会不会吃帽子。 代码 Github地址&#xff1a;https://github.com/ultralytics/ultralytics 预训练权重下载地址&#xff1a;https://github.com/ultralytics…

基于单片机温湿度光照自动窗帘系统设计

**单片机设计介绍&#xff0c; 基于单片机温湿度光照自动窗帘系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的温湿度光照自动窗帘系统是一种智能家居系统&#xff0c;通过使用单片机作为控制核心&#xff0c…

奇异值分解SVD(singular value decomposition)

奇异值分解 SVD是一个很有用的矩阵因子化方法。 SVD提出的目的&#xff1a;任何一个 m n m\times n mn的矩阵都可以当作一个超椭圆&#xff08;高维空间的椭圆&#xff09;&#xff0c;可以把它们当作单位球体S的像。 一个超椭圆可以通过将单位球型在正交方向 u 1 , u 2 , . …

Prometheus的详细部署

普罗米修斯下载网址: Download | Prometheus 准备两台机器&#xff1a; 192.168.58.152 prometheus 192.168.58.142 node_exporter 关闭防火墙和selinux&#xff1a; [rootlocalhost ~]# setenforce 0 && systemctl stop firewalld[rootlocalhost ~]# seten…

[机缘参悟-120] :计算机世界与佛家看世界惊人的相似

目录 前言&#xff1a; 一、计算机 - 有序性不过是人为设计出来的&#xff01;&#xff01;&#xff01; 1.1 破相1&#xff1a;计算机的物质基础不过是一堆电子元器件的机缘组合 1.2 破相2&#xff1a;计算机不过是各种电信号的有序运动&#xff08;有序是关键&#xff09…

【c++|SDL】二、读取图片、显示图片、动画制作

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 读取图片&#xff0c;显示图片&#xff0c;动画 SDL中有两种在屏幕上显示的方法 SDL_Surface: 使用软件渲染处理SDL_Texture: 使用硬件加速渲染处理 1.…

C++二分查找、离线算法:最近的房间

作者推荐 利用广度优先或模拟解决米诺骨牌 本文涉及的基础知识点 二分查找算法合集 题目 一个酒店里有 n 个房间&#xff0c;这些房间用二维整数数组 rooms 表示&#xff0c;其中 rooms[i] [roomIdi, sizei] 表示有一个房间号为 roomIdi 的房间且它的面积为 sizei 。每一…