Spring 创建和使用

Spring 是⼀个包含了众多⼯具⽅法的 IoC 容器。既然是容器那么它就具备两个最基本的功能:

将对象存储到容器(Spring)中; 从容器中将对象取出来。  

在 Java 语⾔中对象也叫做 Bean

1.创建 Spring 项目 

接下来使⽤ Maven ⽅式来创建⼀个 Spring 项⽬,创建 Spring 项⽬和 Servlet 类似,总共分为以下 3 步:

1. 创建⼀个普通 Maven 项⽬。

2. 引入 Spring 依赖(spring-context、spring-beans)。

3. 添加启动类。

1.1 创建⼀个 Maven 项目

1.2 引入 Spring 依赖

在项⽬的 pom.xml 中添加 Spring 框架的⽀持,xml 配置如下:

<dependencies>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context</artifactId>
 <version>5.2.3.RELEASE</version>
 </dependency>
 
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-beans</artifactId>
 <version>5.2.3.RELEASE</version>
 </dependency>
</dependencies>

从上述配置中可以看出,添加的框架有 spring-context:spring 上下⽂,还有 spring-beans:管理对 象的模块。 

1.3 添加启动类

最后在创建好的项⽬ java ⽂件夹下创建⼀个启动类,包含 main ⽅法即可:

 2.存储 Bean 对象

存储 Bean 分为以下 2 步:

1. 存储 Bean 之前,先得有 Bean 才⾏,因此先要创建⼀个 Bean。

2. 将创建的 Bean 注册到 Spring 容器中。 具体实现如下。

2.1 创建 Bean

所谓的 Bean 就是 Java 语⾔中的⼀个普通对象,实现代码如下:

public class User {
    private String name;
    private Integer age;

    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;
    }
}

2.2 将 Bean 注册到容器

在创建好的项⽬中添加 Spring 配置⽂件 spring-config.xml,将此⽂件放到 resources 的根⽬录下, 如下图所示:

Spring 配置⽂件的固定格式为以下内容(以下内容⽆需记忆,只需要保存到⾃⼰可以找到的地⽅就可以 了,因为它是固定不变的):

<?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">

</beans>

接下来,再将 User 对象注册到 Spring 中就可以,具体操作是在 中添加如下配置

<beans>
 <bean id="user" class="org.example.User"></bean>
</beans>

3.获取并使⽤ Bean 对象:

获取并使⽤ Bean 对象,分为以下 3 步:

1. 得到 Spring 上下⽂对象,因为对象都交给 Spring 管理了,所以获取对象要从 Spring 中获取,那 么就得先得到 Spring 的上下⽂。

2. 通过 Spring 上下⽂,获取某⼀个指定的 Bean 对象。

3. 使⽤ Bean 对象。

(如果取多个 Bean 的话重复以上第 2、3 步骤。)

3.1 创建 Spring 上下文

Spring 上下⽂对象可使⽤ ApplicationContext,实现代码如下:

// 1.得到 Spring 的上下⽂对象,创建的时候需要配置 Spring 配置信息
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

ApplicationContext:Spring的运行环境 

除了 ApplicationContext 之外,我们还可以使⽤ BeanFactory 来作为 Spring 的上下⽂,如下代码所 示:

BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

ApplicationContext 和 BeanFactory 效果是⼀样的,ApplicationContext 属于 BeanFactory 的⼦ 类,它们的区别如下。

ApplicationContext VS BeanFactory(常⻅⾯试题)

共同点:都是获取Spring bean

继承关系和功能⽅⾯来说:Spring 容器有两个顶级的接⼝:BeanFactory 和 ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ ApplicationContext 属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性, 还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持。

从性能⽅⾯来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,⽽ BeanFactory 是需要那个才去加载那个,因此更加轻量

⽽ ClassPathXmlApplicationContext 属于 ApplicationContext 的⼦类,拥有 ApplicationContext 的所有功能,是通过 xml 的配置来获取所有的 Bean 容器的。

3.2 获取指定的 Bean 对象 

// 1.得到 Spring 上下⽂对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
// 2.加载某个 bean
User user = (User) context.getBean("user");

3.2.1 注意事项

Bean 的 Id 要⼀⼀对应,如下图所示:

3.2.2 getBean 方法的更多用法 

getBean() ⽅法有很多种重载⽅法,我们也可以使⽤其他⽅式来获取 Bean 对象,⽐如以下这两种:

1、根据类型获取 Bean:

UserController user = context.getBean(UserController.class);

2、名称 + 类型获取 Bean: 

UserController user = context.getBean("user", UserController.class);

⼆者的区别:当有⼀个类型被重复注册到 spring-config.xml 中时,只能使⽤根据名称获取了

不论我们拿多少次,或者使用那种方式取对象,获取的都是同一个对象

3.3 使⽤ Bean 

public class App {
 public static void main(String[] args) {
 // 1.得到 Spring 上下⽂对象
 ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");
 // 2.加载某个 bean
 User user = (User) context.getBean("user");
 // 3.调⽤相应的⽅法
 System.out.println(user.sayHi("Java"));
 }
}

4.总结

1. 操作容器之前,先要有容器,所以先要得到容器。

2. 存对象

a. 创建 Bean(普通类)。

b. 将 Bean 注册(配置)到 spring-confing.xml 中。

3. 取对象

a. 得到 Spring 上下⽂,并读取到 Spring 的配置⽂件。

b. 获取某⼀个 Bean 对象。

c. 使⽤ Bean 对象。

操作流程如下图所示:

5.Spring 更简单的读取和存储对象 

在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解

5.1.存储 Bean 对象

之前我们存储 Bean 时,需要在 spring-config 中添加⼀⾏ bean 注册内容才⾏,如下图所示:

⽽现在我们只需要⼀个注解就可以替代之前要写⼀⾏配置的尴尬了,不过在开始存储对象之前,我们先 要来点准备⼯作。 

5.1.1 前置⼯作:配置扫描路径(重要)

注意:想要将对象成功的存储到 Spring 中,我们需要配置⼀下存储对象的扫描包路径,只有被配置的 包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。

在 spring-config.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"
       xmlns:content="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package="org.example"></content:component-scan>
</beans>

 也就是说,即使添加了注解,如果不是在配置的扫描包下的类对象,也是不能被存储到 Spring 中的。

5.1.2 添加注解存储 Bean 对象

想要将对象存储在 Spring 中,有两种注解类型可以实现:

1. 类注解:@Controller、@Service、@Repository、@Component、@Configuration。

2. ⽅法注解:@Bean。

 @Controller(控制器存储)

使⽤ @Controller 存储 bean 的代码如下所示:

@Controller // 将对象存储到 Spring 中
public class UserController {
    public void sayHi(){
        System.out.println("hi,userController");
    }
}

此时我们先使⽤之前读取对象的⽅式来读取上⾯的 UserController 对象,如下代码所示:

public class App {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean
        UserController userController = (UserController) context.getBean("userController");
        // 3.调⽤ bean ⽅法
        userController.sayHi();
    }
}

@Service(服务存储) 

使⽤ @Service 存储 bean 的代码如下所示:

@Service
public class UserService {
    public void doService(){
        System.out.println("userService");
    }
}

读取 bean 的代码:

public class App {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean
        UserService userService = (UserService)context.getBean("userService");
        // 3.调⽤ bean ⽅法
       
        userService.doService();
    }
}

 @Repository(仓库存储)

使⽤ @Repository 存储 bean 的代码如下所示:

@Repository
public class UserRepository {
    public void sayHi(){
        System.out.println("hi,userRepository");
    }
}

读取 bean 的代码:

public class App {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean
      UserRepository userRepository= (UserRepository) context.getBean("userRepository");
        userRepository.sayHi();
    }
}

@Component(组件存储)

使⽤ @Component 存储 bean 的代码如下所示:

@Component
public class UserComponent {
    public void sayHi(){
        System.out.println("hi,userComponent");
    }
}

读取 bean 的代码:

public class App {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean
     UserComponent userComponent= (UserComponent) context.getBean("userComponent");
        userComponent.sayHi();
    }
    }
}

@Configuration(配置存储)

使⽤ @Configuration 存储 bean 的代码如下所示:

@Configuration
public class UserConfiguration {
    public void sayHi(){
        System.out.println("hi,Configuration");
    }

}

读取 bean 的代码:

public class App {
    public static void main(String[] args) {
        // 1.得到 spring 上下⽂
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2.得到 bean
     UserConfiguration userConfiguration= (UserConfiguration) context.getBean("userConfiguration");
        userConfiguration.sayHi();
    }
    }
}

5.1.3 为什么要这么多类注解?

为什么需要怎么多的类注解的原因,就是让程序员看到类注解之后,就能直接了解当前类 的⽤途,⽐如:

@Controller:表示的是业务逻辑层;控制器,通常是指程序的入口,比如参数校验,参数类型转换,前置处理工作...

@Servie:服务层;一般写业务代码,服务编排

@Repository:持久层;仓库,通常是指DB操作相关的代码

@Configuration:配置层;

@Component : 其他对象。

程序的⼯程分层,调⽤流程如下:

 5.1.3.1 类注解之间的关系

查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现:

 其实这些注解⾥⾯都有⼀个注解 @Component,说明它们本身就是属于 @Component 的“⼦类”。

5.1.3.2 Bean 命名 

通过上⾯示例,我们可以看出,通常我们 bean 使⽤的都是标准的⼤驼峰命名,⽽读取的时候⾸字⺟⼩ 写就可以获取到 bean 了,如下图所示:

 然⽽,当我们⾸字⺟和第⼆个字⺟都是⼤写时,就不能正常读取到 bean 了,如下图所示:

 这个时候,我们就要查询 Spring 关于 bean 存储时⽣成的命名规则了。

我们可以在 Idea 中使⽤搜索关键字“beanName”可以看到以下内容:

顺藤摸⽠,我们最后找到了 bean 对象的命名规则的⽅法:

它使⽤的是 JDK Introspector 中的 decapitalize ⽅法,源码如下: 

public static String decapitalize(String name) {
 if (name == null || name.length() == 0) {
 return name;
 }
 // 如果第⼀个字⺟和第⼆个字⺟都为⼤写的情况,是把 bean 的⾸字⺟也⼤写存储了
 if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
 Character.isUpperCase(name.charAt(0))){
 return name;
 }
 // 否则就将⾸字⺟⼩写
 char chars[] = name.toCharArray();
 chars[0] = Character.toLowerCase(chars[0]);
 return new String(chars);
}

所以对于上⾯报错的代码,我们只要改为以下代码就可以正常运⾏了:

5.1.4 方法注解 @Bean

类注解是添加到某个类上的,⽽⽅法注解是放到某个⽅法上的,如以下代码的实现:

public class Users {
 @Bean
 public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
 }
}

然⽽,当我们写完以上代码,尝试获取 bean 对象中的 user1 时却发现,根本获取不到: 

public class Application {
 public static void main(String[] args) {
 ApplicationContext context =
 new ClassPathXmlApplicationContext("spring-config.xml");
 User user = (User) context.getBean("user1");
 System.out.println(user.toString());
 }
}

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

在 Spring 框架的设计中,⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中,如 下代码所示:

@Component
public class Users {
 @Bean
 public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
 }
}

再次执⾏以上代码,运⾏结果如下:

5.1.4.2 重命名 Bean 

可以通过设置 name 属性给 Bean 对象进⾏重命名操作,如下代码所示:

@Component
public class Users {
 @Bean(name = {"u1"})
 public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
 }
}

此时我们使⽤ u1 就可以获取到 User 对象了,如下代码所示:

class App {
 public static void main(String[] args) {
 // 1.得到 spring 上下⽂
 ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");
 // 2.得到某个 bean
 User user = (User) context.getBean("u1");
 // 3.调⽤ bean ⽅法
 System.out.println(user);
 }
}

 这个重命名的 name 其实是⼀个数组,⼀个 bean 可以有多个名字:

@Bean(name = {"u1", "us1"})
public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
}

并且 name={} 可以省略,如下代码所示:

@Bean({"u1", "us1"})
public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
}

5.2.获取 Bean 对象(对象装配)

获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊。

对象装配(对象注⼊)的实现⽅法以下 3 种:

1. 属性注⼊ 2. 构造⽅法注⼊ 3. Setter 注⼊

5.2.1 属性注⼊

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

属性注⼊的核⼼实现如下:

@Controller
public class UserController {
    @Autowired
    private UserService userService;

    public void sayHi(){
        userService.doService();
        System.out.println("hi,userController");
    }
}

5.2.2 构造⽅法注⼊

构造⽅法注⼊是在类的构造⽅法中实现注⼊,如下代码所示:

@Controller
public class UserController3 {

    private UserService us;

    private UserConfiguration userConfiguration;

    @Autowired
    public UserController3(UserService us) {
        this.us = us;
    }

    public UserController3(UserService us, UserConfiguration userConfiguration) {
        this.us = us;
        this.userConfiguration = userConfiguration;
    }

    @Autowired
    public void setUs(UserService us){
        this.us = us;
    }
    public void sayHi(){
        us.doService();
        System.out.println("hi,userController3");
    }
}

注意事项:如果只有⼀个构造⽅法,那么 @Autowired 注解可以省略 

5.2.3 Setter 注⼊

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

@Controller
public class UserController2 {

    private UserService us;
    @Autowired
    public void setUs(UserService us){
        this.us = us;
    }
    public void sayHi(){
        us.doService();
        System.out.println("hi,userController");
    }
}

5.2.4 三种注⼊优缺点分析

属性注⼊:优点:是简洁,使⽤⽅便;缺点:是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常).不能注入一个final修饰的属性。

构造⽅法注⼊是 Spring 推荐的注⼊⽅式,它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这 种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了,它的优点是通⽤性,在使⽤ 之前⼀定能把保证注⼊的类不为空;

 

Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法,所有 Spring 现版本已 经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了。优点:方便在类实例之后,重新对该对象进行配置或注入。缺点:不能注入一个final修饰的属性。注入对象可能会被改变,因为setter方法可能会被多次调用,就有被修改的方法。

5.2.5 @Resource:另⼀种注⼊关键字

在进⾏类注⼊时,除了可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如 下代码所示

@Controller
public class UserController4 {
    @Resource
    private UserService userService;

    public void sayHi(){
        userService.doService();
        System.out.println("hi,userController4");
    }
}

@Autowired 和 @Resource 的区别

出身不同:@Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解;

使⽤时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。

@Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注 ⼊和属性注⼊,不能⽤于构造函数注⼊。

5.2.6 同⼀类型多个 @Bean 报错 

当出现多个 Bean,返回同⼀对象类型时程序会报错

@Component
public class Users {
 @Bean
 public User user1() {
 User user = new User();
 user.setId(1);
 user.setName("Java");
 return user;
 }
 @Bean
 public User user2() {
 User user = new User();
 user.setId(2);
 user.setName("MySQL");
 return user;
 }
}

在另⼀个类中获取 User 对象,如下代码如下:

@Controller
public class UserController4 {
 // 注⼊
 @Resource
 private User user;
 public User getUser() {
 return user;
 }
}

 以上程序的执⾏结果如下:

报错的原因是,⾮唯⼀的 Bean 对象。

同⼀类型多个 Bean 报错处理 

解决同⼀个类型,多个 bean 的解决⽅案有以下两个:

  • 使⽤ @Resource(name="user1") 定义。
  • 使⽤ @Qualifier 注解定义名称。

① 使⽤ @Resource(name="XXX") 

@Controller
class UserController4 {
 // 注⼊
 @Resource(name = "user1")
 private User user;
 public User getUser() {
 return user;
 }
}

② 使⽤ @Qualifier

@Controller
public class UserController5 {
 // 注⼊
 @Autowired
 @Qualifier(value = "user2")
 private User user;
 public User getUser() {
 return user;
 }
}

6、总结

1. 将对象存储到 Spring 中:

a. 使⽤类注解:@Controller、@Service、@Repository、@Configuration、@Component【它 们之间的关系】

b. 使⽤⽅法注解:@Bean

【注意事项:必须配合类注解⼀起使⽤】

2. Bean 的命名规则:⾸字⺟和第⼆个字⺟都⾮⼤写,⾸字⺟⼩写来获取 Bean,如果⾸字⺟和第⼆个 字⺟都是⼤写,那么直接使⽤原 Bean 名来获取 Bean。

3. 从 Spring 中获取对象:

a. 属性注⼊

b. Setter 注⼊

c. 构造函数注⼊(推荐)

4. 注⼊的关键字有:

a. @Autowired

b. @Resource

5. @Autowired 和 @Resource 区别:

出身不同;使⽤时设置参数不同 @Resource ⽀持更多的参数,⽐如 name。

6. 解决同⼀类型多个 Bean 的报错:

a. 使⽤ @Resource(name="")

b. 使⽤ @Qualifier("")

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

智慧景区综合解决方案52页,多媒体触控系统,顶层设计

导读&#xff1a;原文《智慧景区综合解决方案52页ppt》&#xff08;获取来源见文尾&#xff09;&#xff0c;本文精选其中精华及架构部分&#xff0c;逻辑清晰、内容完整&#xff0c;为快速形成售前方案提供参考。 完整版领取方式 完整版领取方式&#xff1a; 如需获取完整的电…

Python面向对象(三)(继承、封装)

面向对象的三大特性 面向对象编程&#xff0c;是许多编程语言都支持的一种编程思想。 简单理解是&#xff1a;基于模板&#xff08;类&#xff09;去创建实体&#xff08;对象&#xff09;&#xff0c;使用对象完成功能开发。 面向对象包含3大主要特性&#xff1a; 封装 封…

静态 链接

1、空间与地址的分配 现在的链接器空间分配的策略基本上都采用 “相似段合并” 的方式。通过将所有相同类型的 section 合并到一起&#xff0c;例如将所有输入目标文件的 .text 合并&#xff08;按顺序合并&#xff09;到输出文件的 .text 节中&#xff1b;然后&#xff0c;链接…

机器学习之线性判别分析(Linear Discriminant Analysis)

1 线性判别分析介绍 1.1 什么是线性判别分析 线性判别分析&#xff08;Linear Discriminant Analysis&#xff0c;简称LDA&#xff09;是一种经典的监督学习算法&#xff0c;也称"Fisher 判别分析"。LDA在模式识别领域&#xff08;比如人脸识别&#xff0c;舰艇识别…

链表踏歌:独具慧眼,雕琢重复元素藏身匿迹

本篇博客会讲解力扣“83. 删除排序链表中的重复元素”的解题思路&#xff0c;这是题目链接。 由于链表是排好序的&#xff0c;我们可以通过遍历一次链表的方式&#xff0c;删除所有重复的结点。具体来说&#xff0c; 如果链表为空&#xff0c;则不需要删除&#xff0c;直接返回…

全加器(多位)的实现

一&#xff0c;半加器 定义 半加器&#xff08;Half Adder&#xff09;是一种用于执行二进制数相加的简单逻辑电路。它可以将两个输入位的和&#xff08;Sum&#xff09;和进位&#xff08;Carry&#xff09;计算出来。 半加器有两个输入&#xff1a;A 和 B&#xff0c;分别代表…

GPT和MBR的区别

磁盘分区是操作系统管理磁盘数据的一项非常重要的功能。在分区时&#xff0c;用户需要选择一种分区表格式来组织磁盘上的分区&#xff0c;这也就是GPT和MBR两种分区表格式的由来。在本文中&#xff0c;将详细探讨GPT和MBR分区表格式的区别和如何选择它们。 1. MBR和GPT分区表格…

有关 openAPI 的一些总结

目前主流的 APi 的验证是&#xff1a;Tokensign sign 主要是保证数据的真实性 token 主要是进行接口安全访问的 sign验证签名&#xff08; sha256Hex&#xff09; 一般将一些平台的版本及平台 id 等字段进行固定拼接后再进行摘要算法处理 // 参与签名计算的Key-Value列表 Map…

【C语言敲重点(五)】嵌入式“八股文“(2)

1. struct和union的区别&#xff1f; 答&#xff1a;①联合体所有的成员都共享一块内存&#xff0c;修改联合体的任一成员的数据就会覆盖到其他成员的数据&#xff1b; ②结构体的成员变量都有独立的内存空间&#xff0c;且结构体的成员数据之间是不影响的 2. struct和class的…

LeetCode第 N 个泰波那契数 (认识动态规划)

认识动态规划 编写代码代码空间优化 链接: 第 N 个泰波那契数 编写代码 class Solution { public:int tribonacci(int n) {if(n 0){return 0;}else{if(n 1 || n 2)return 1;}vector<int> dp(n 1);dp[0] 0;dp[1] 1;dp[2] 1;for(int i 3;i < n;i){dp[i] dp[i-3]…

Upload文件导入多条数据到输入框

需求场景&#xff1a;文本框内容支持批量导入(文件类型包括’.txt, .xls, .xlsx’)。使用AntD的Upload组件处理。 下面是Upload的配置&#xff08;伪代码&#xff09;&#xff0c;重点为beforeUpload中的逻辑 // Antd 中用到的Upload组件 import { UploadOutlined } from ant…

汽车养护店服务难题,看帕凝怎样解决?

中国汽车市场庞大&#xff0c;入户已然成为标配&#xff0c;加之新能源汽车近些年高增量&#xff0c;更促进了行业增长。而汽车后市场也迎来了一系列变化&#xff0c;客户服务前后路径需完善&#xff0c;商家们应该如何数字化经营呢&#xff1f; 接下来让我们看看【帕凝汽车养…

NOI Linux 2.0 CSP奥赛复赛环境安装使用指南

新人旧人区别 以下是可能导致你在老版 NOI Linux 系统下形成的习惯在新版下翻车的改动。 移除了 GUIDE从 32bit 变为了 64bit 系统&#xff0c;需要注意指针现在占 8 字节而不是 4 字节更新了编译器版本默认情况下右键没了【新建文件】的选项桌面目录改为中文&#xff0c;可能…

7.Docker-compose

文章目录 Docker-compose概念Docker-compose部署YAML文件格式和编写注意事项注意数据结构对象映射序列属组布尔值序列的映射映射的映射JSON格式文本换行锚点和引用 Docker compose配置常用字段docker compose常用命令Docker Compose 文件结构docker compose部署apachedocker co…

【图像分割】基于蜣螂优化算法DBO的Otsu(大津法)多阈值电表数字图像分割 电表数字识别【Matlab代码#51】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第5节&#xff1a;资源获取】1. 原始蜣螂优化算法1.1 滚球行为1.2 跳舞行为1.3 繁殖行为1.4 偷窃行为 2. 多阈值Otsu原理3. 部分代码展示4. 仿真结果展示5. 资源获取说明 【可更换其他算法&#xff0c;获取资源请见文章第…

RTOS 低功耗设计原理及实现

RTOS 低功耗设计原理及实现 文章目录 RTOS 低功耗设计原理及实现&#x1f468;‍&#x1f3eb;前言&#x1f468;‍&#x1f52c;Tickless Idle Mode 的原理及实现&#x1f468;‍&#x1f680;Tickless Idle Mode 的软件设计原理&#x1f468;‍&#x1f4bb;Tickless Idle Mo…

Jmap-JVM(十六)

上篇文章说了ZGC是jdk11加入的&#xff0c;他是未来jvm垃圾收集器的奠定者&#xff0c;满足TB级别内存处理&#xff0c;STW时间保持在10ms以下。 Jmap 我们可以先通过jmap -histo 进程ip 来查看&#xff0c;但是这样看不太清晰&#xff0c;我们可以用这行命令生成一个文件&…

WebDAV之π-Disk派盘+ WinSCP

WinSCP是一个免费的开源文件传输应用程序&#xff0c;它使用文件传输协议&#xff0c;安全外壳文件传输协议和安全复制协议来进行纯文件或安全文件传输。该应用程序旨在与Windows一起使用&#xff0c;并支持常见的Windows桌面功能&#xff0c;例如拖放文件&#xff0c;跳转列表…

设计模式结构型——代理模式

目录 代理模式的用途 代理模式的实现 静态代理 JDK动态代理 CGLIB动态代理 代理模式的特点 与其他模式比较 代理模式&#xff08;Proxy Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许通过创建一个代理对象来间接访问原始对象。代理模式的核心思想是将对目…

预科C语言

1.day10 1、perror() 原型&#xff1a;void perror(const char *s); 根据errno呈现错误信息 perror("malloc error"); malloc error: Cannot allocate memory 2、多文件编译 .c ---预处理&#xff08;.i -E&#xff09;---汇编&#xff08;.s -S&#xf…