Spring更简单的存取Bean

news2024/12/26 23:07:04

在上一篇blog里边我介绍了spring项目的创建以及Bean对象的存储和读取。

存储:1.首先创建Bean对象 2.将Bean对象注册到Spring容器中【Bean标签】

读取:1.获取Spring上下文对象 2.获取指定的Bean对象 3.使用Bean对象

但是随着Bean对象的增多以及使用频率的提高,上述过程难免有点效率低,所以需要学习下边更为简单的存取Bean对象的方式——使用注解,这也是Spring中更为简单存取Bean对象的核心。

一、存储Bean对象

0.准备工作:配置扫描路径(关键)

只有正确配置存储对象的扫描包路径,对应包下的类才能被正确识别并保存。

配置方法:

在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.spring
framework.org/schema/context https://www.springframework.org/schema/contex
t/spring-context.xsd">
<content:component-scan base-package="com.bit.service"></content:component-scan>
</beans>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RkYxdegH-1683543406415)(F:\typora插图\image-20230508151930542.png)]

1.添加注解存储Bean对象

将对象注册到Spring中,有两种注解类型可以实现。分别是

1)五大类注解:@Controller、@Service、@Respository、@Component、@Configuration

2)一个方法注解:@Bean

1.1类注解

1.1.1@Controller

@Controller其实也叫做控制器注解,它的作用是验证用户请求数据的正确性,类似于安保系统。当认定当前访问者为非法用户黑客,就把他们加入黑名单。

下边是利用此注解存储Bean的代码示例:

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

将这个注解加到类上边,当需要用到这个类的对象时,spring就会自动获取。

这里为了演示效果,我们先使用之前获取Bean的方法读取上述对象:

public class Application {
public static void main(String[] args) {
        ApplicationContext context =
        new ClassPathXmlApplicationContext("spring-config.xml");
        UserController userController = (UserController) context.getBean("userController",UserController.class);
        userController.sayHi();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3H59DUOR-1683543406416)(F:\typora插图\image-20230508153320756.png)]

这样我们就拿到了这个对象

1.1.2@Service

@Service注解其实也叫做服务注解。它的作用就是编排和调度具体执行方法,在服务层,相当于导医台/服务中心,完成引导工作,但是不执行业务。

下边是使用@Service注解存储对象的代码示例:

@Service
public class UserService {
    public void sayHi(String name) {
    System.out.println("do UserService sayHi()");
    }
}

读取Bean对象(老方法):

public class App {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//        UserController userController=context.getBean("userController",UserController.class);
//        userController.sayHi();
        UserService userService=context.getBean("userService",UserService.class);
        userService.sayHi();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mv3uSjt1-1683543406416)(F:\typora插图\image-20230508154039705.png)]

1.1.3剩余的类注解

剩余的三个注解使用方法与之类似,这里一并演示

@Repository也叫做仓库存储,是在数据持久层即和数据库进行交互的一层,其中数据库在程序中就叫做仓库。

@Component其实也叫做组件存储,是操作数据的工具类。

@Configuration其实也叫做配置存储,是用来存项目中的一些配置的。

存对应Bean方法

@Configuration
public class UserConfiguration {
    public void sayHi(){
        System.out.println("do UserConfiguration sayHi()");
    }
}
@Repository
public class UserRepository {
    public void sayHi(){
        System.out.println("do UserRepository sayHi()");
    }
}
@Component
public class UserComponent {
    public void sayHi(){
        System.out.println("do UserComponent sayHi()");
    }
}

取对象方法:

public class App {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
//        UserController userController=context.getBean("userController",UserController.class);
//        userController.sayHi();
//        UserService userService=context.getBean("userService",UserService.class);
//        userService.sayHi();
        UserRepository userRepository=context.getBean("userRepository",UserRepository.class);
        UserComponent userComponent=context.getBean("userComponent",UserComponent.class);
        UserConfiguration userConfiguration=context.getBean("userConfiguration",UserConfiguration.class);
        userComponent.sayHi();
        userConfiguration.sayHi();
        userRepository.sayHi();
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DRv6zgpf-1683543406417)(F:\typora插图\image-20230508155204399.png)]

1.2 五大类注解之间的关系

1.2.1.为什么需要这么多种类注解

为了让程序员看到类注解之后就能直接知道当前类的用途。

例如:@Controller:表示业务逻辑层

@Service:表示服务层

@Repository:表示持久层

@Configuration:表示配置层

了解程序的工程分层会对这个作用有进一步的认识:

JavaEE标准分层至少三个:控制层、服务层、数据持久层,一般公司会在此基础上进行扩展。

这里有配置层是因为有时候感知不到配置文件,所以通过注解告诉他。所以一个项目的配置可能在配置文件或者配置层中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XEi5Eoj3-1683543406417)(F:\typora插图\image-20230508160107973.png)]

1.2.2 类注解之间的关系

通过ctrl+左键,我们可以看到五大类注解的源码是这样的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jAwStRo0-1683543406418)(F:\typora插图\image-20230508161108986.png)]

通过观察,我们不难发现,@Controller / @Service / @Repository / @Configuration 这四个类注解都是基于@Component这个注解实现的。

1.3 方法注解

见名知义,类注解是加在类上的,方法注解是加在方法上的。

使用方法注解,其实就是把表示当前方法的返回值将被装配到容器中。

使用方法:在当前方法上加上@Bean 注解,在方法所属类上边加上对应的类注解。即方法注解必须结合类注解使用。

下边是代码示例:

数据准备:创建实体类User。其中@Setter和@Getter以及@ToString注解是lombok插件提供的自动生成对应类的get、set和toString方法的注解(可略)。

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class User {
    private int id;
    private String name;
    public void sayHi(){
        System.out.println("do User sayHi()");
    }

}

实体类:数据库中有一张表,代码中就会有一个对应的实体类,有一个容器去承接对应的实体类,这个实体类中的属性就对应表中的字段。

对应的包名:entity/model

实体类命名规则:

1.基本对象对应数据库中的一张表:与表名一致

2.扩展对象:xxxinfo/xxxinfoVO

组件层的代码:

@Component
public class UserComponent {
    @Bean
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("Java");
        return user;
    }
    public void sayHi(){
        System.out.println("do UserComponent sayHi()");
    }
}

启动类:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a7KLt3ez-1683543406418)(F:\typora插图\image-20230508163704329.png)]

1.4 Bean命名规则

不难发现,通常来讲Bean,我们使用的都是标准的大驼峰命名,而使用getBean读取的时候则是使用首字母小写+类类型获取的:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lD6CGCkc-1683543406418)(F:\typora插图\image-20230508164119689.png)]

当我们将首字母也写成大写时就会发现有如下错误:NoSuchBeanDefinationException即没有找到Bean异常其实也就是注入失败
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z5Y9CSNa-1683543406419)(F:\typora插图\image-20230508164313626.png)]

因为我们是使用的注解的方式自动注入的,所以Bean的命名是由Spring决定的,根据报错我们不难想到,需要查看Spring关于bean存储生成的规则:

查看方法:双击shift出发全局搜索,输入BeanName,点击AnnotationbeanName…[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nd56qfBl-1683543406419)(F:\typora插图\image-20230508164914466.png)]

观察并分析:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HMlJm5er-1683543406420)(F:\typora插图\image-20230508165714654.png)]

结论:默认情况下是首字母小写,如果类名是首字母和次字母都是大写,那么Bean名称就是它的类型名。

二、获取Bean对象

获取Bean对象也叫做对象装配或者对象注入(从Spring容器中拿出来给当前类装配上/注入,相当于一个完成工作必须的部件)。

对象装配实现方法有三种:

  1. 属性注入
  2. 构造方法注入
  3. Setter注入

其中属性注入最简单,实际开发中使用的也最多。构造方法是官方推荐的注入方式,官方给予的支持也很大,稍后详细说一下。

1.属性注入

属性注入实现方法:在对象上添加@Autowired注解。其中autowired是自动连线的意思。

将Service类注入到Controller类中,其中Service连接着数据持久层操作数据库即将Repository类注入到Service类中。

示例:

数据准备:UserRepository类代码:

@Repository
public class UserRepository {
    @Autowired
    private User user=new User();
    @Bean
    public User getUser(){
        return user;
    }
    public void sayHi(){
        System.out.println("do UserRepository sayHi()");
    }
}

UserService类代码:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public User getUser(Integer id) {
        return userRepository.getUser();
    }
//    public void sayHi(){
//        System.out.println("do UserService sayHi()-->"+userRepository.getUser());
//    }
}

UserController类代码:

@Controller
public class UserController {
    @Autowired
    private UserService userService;
    public User getUser(Integer id) {
        return userService.getUser(id);
    }
//    public void sayHi(){
//        System.out.println("do UserController sayHi()");
//    }
}

获取数据:

public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");

        UserController userController = context.getBean(UserController.class);
        System.out.println(userController.getUser(1).toString());
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8NqhBlJv-1683543406420)(F:\typora插图\image-20230508171810898.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q7D7wHj4-1683543406420)(F:\typora插图\image-20230508171944138.png)]

2.构造方法注入

实现方法:在类的构造方法中实现注入,@Autowired注解加载构造方法上

示例:

@Controller
public class UserController2 {
    private UserService userService;
    @Autowired
    public UserController2(UserService userService) {
    	this.userService = userService;
    }
    public User getUser(Integer id) {
    	return userService.getUser(id);
    }
}
public class App {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");

        UserController2 userController = context.getBean(UserController2.class);
        System.out.println(userController.getUser(1).toString());
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XlrVw9JK-1683543406421)(F:\typora插图\image-20230508173014786.png)]

注意:当只有一个构造方法时,@Autowired注解可以省略(官方开的绿灯)

当多个构造方式时,必须明确指定到底哪一个构造方法使用@Autowired,否则程序会报错。如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CA2J3aU9-1683543406421)(F:\typora插图\image-20230508173617824.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wx2UmqRX-1683543406422)(F:\typora插图\image-20230508174554448.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TRTR1dhx-1683543406422)(F:\typora插图\image-20230508173925122.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vWrxSzj2-1683543406423)(F:\typora插图\image-20230508174326243.png)]

通过观察我们还可以发现:无参构造很重要,如果我们自己写了一个或多个有参构造方法,就必须要在其中一个上边加@Autowired注解,指定使用哪个进行实例化。

或者说如果我们没标,它回去找无参构造没有就报错注入失败;如果我们标了,就必须是唯一的。

3.Setter方法注入

实现方法:与属性的Setter方法类似, 需要在设置 set ⽅法的时候需要加上 @Autowired 注解。

@Controller
public class UserController3 {
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
    	this.userService = userService;
    }
    public User getUser(Integer id) {
    	return userService.getUser(id);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cKZ0KL0U-1683543406423)(F:\typora插图\image-20230508175208776.png)]

思考:set ⽅法如果不加 @Autowired 注解能注⼊成功 吗?

答:不能。注意这里不是注入成功了得到空对象了,因为如果是得到空对象了,返回的就是NULL而不是报错。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nB1WKzNY-1683543406424)(F:\typora插图\image-20230508175827735.png)]

三种注入方法的对比

类别优点缺点
属性注入简洁,使用方便1.功能上,没办法实现final修饰变量注入 2.兼容性上,兼容性不好,只适用于IoC容器 3.风险性上,写法简单,违背单一设计原则概率更大
构造方法注入1.可注入一个不可变对象 2.注入的对象不会被改变,构造方法只执行一次 3.通用性更好,所有的框架都支持构造方法 4.构造方法保证注入对象完全被初始化当有多个注入时会比较臃肿
Setter注入符合单一设计原则,因为只会赋值给一个对象1.不可注入不可变对象 2.注入的对象可能会被修改重置

从上边可以看出,对象的注入都是基于@Autowired这个注解实现的

另一种注入关键字:@Resource

@Resource是由jdk提供的注入关键字,@Autowired是由spring提供的。

使用方法:与autowired类似,放在属性上或者方法上,但是只能放在autowired上,不能用于构造方法,会直接报错。

使用示例:

@Controller
public class UserController4 {
    private UserService userService;
    @Resource//Setter注入
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jsKiNZVr-1683543406424)(F:\typora插图\image-20230508181058766.png)]

@Controller
public class UserController4 {
    @Resource//属性注入
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public User getUser(Integer id) {
        return userService.getUser(id);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NYeGUXQY-1683543406425)(F:\typora插图\image-20230508181143601.png)]

@Autowired和@Resource区别

相同点功能上都只能完成对象装配的工作
不同点1.来源不同,@Autowired来自spring,@Resource来自 2.支持用法不同,@Autowired支持属性注入、构造方法注入和Setter注入三种方式,而@Resource只支持属性注入和Setter方法注入两种方式 3.参数设置上不同,@Resoure支持更多的参数设置

实际工作,大部分场景下,两个没有区别,除非特殊情景。

同一类型多个Bean报错

在同一个类中,出现多个Bean,返回同一对象类型时,或者不同类中向Spring中注入相同类型的Bean时,程序可能会报错NoUniqueBeanDefinitionException即非唯一的Bean对象。

解决办法:

方案1:使用@Resource(name=“xxx”)进行定义(即起别名)

方案2:使用@Qualifier注解定义名称

方案一代码示例:

@Controller
class UserController5 {
    @Resource(name = "user1")
    private User user;
    public User getUser() {
    	return user;
    }
}

方案二代码示例:

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

@Autowired、@Resource以及Bean在重命名方面区别

通过看源代码很容易发现,这三个注解都可以通过属性的设置实现对Bean重命名的效果。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JZ5rJF7O-1683543406425)(F:\typora插图\image-20230508183205111.png)]

默认情况下,spring的标识符要么是默认的,要么是指定Bean的name属性定义的,要么是Qualifier使用value定义的,要么是Resource的name指定的。

注意:1.重命名后,原来的默认方法名就不可以用了

@Order注解的作用

@Order 是用来控制Bean的执行顺序/优先级的而并非加载顺序。

注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响;

扫描路径与注解读取相关问题

  1. bean标签能不能与component-scan(组件扫描和路径)一起使用

  2. 五大类注解能不能不再component-scan下
    不能,。

  3. 在component-scan下,但是如果没有加五大类注解,能不能把当前对象加到spring容器中的

    不能。

  4. 不同包下的同名类:

    不可以(存储/load时就不行)
    两种解决方法:

    1. 直接改名字

    2. 起别名value选项定义同名类名(默认时null,其他的也是可以设置的)

    取对象的时候导包也要改
    认情况下,spring的标识符要么是默认的,要么是指定Bean的name属性定义的,要么是Qualifier使用value定义的,要么是Resource的name指定的。

注意:1.重命名后,原来的默认方法名就不可以用了

@Order注解的作用

@Order 是用来控制Bean的执行顺序/优先级的而并非加载顺序。

注解@Order或者接口Ordered的作用是定义Spring IOC容器中Bean的执行顺序的优先级,而不是定义Bean的加载顺序,Bean的加载顺序不受@Order或Ordered接口的影响;

扫描路径与注解读取相关问题

  1. bean标签能不能与component-scan(组件扫描和路径)一起使用

  2. 五大类注解能不能不再component-scan下
    不能,。

  3. 在component-scan下,但是如果没有加五大类注解,能不能把当前对象加到spring容器中的

    不能。

  4. 不同包下的同名类:

    不可以(存储/load时就不行)
    两种解决方法:

    1. 直接改名字

    2. 起别名value选项定义同名类名(默认时null,其他的也是可以设置的)

    取对象的时候导包也要改
    建议:尽量避免起相同类名

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

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

相关文章

【面试】Java 反射机制(常见面试题)

文章目录 前言一、反射是什么&#xff1f;二、为什么要有反射三、反射 API3.1 获取 Class 对象的三种方式3.2 获取成员变量3.3 获取构造方法3.4.获取非构造方法 四、实践五、常见面试题5.1. 什么是反射&#xff1f;5.2. 哪里用到反射机制&#xff1f;5.3. 什么叫对象序列化&…

IDEA沉浸式编程体验

前言 IntelliJ IDEA:前不久推出了一个新的概念Fleet编辑器。用过的人都知道&#xff0c;不过是模仿VScode整一套&#xff0c;但相比之下&#xff0c;fleet虽然在传统IDEA的基础上简约了不少&#xff0c;一旦打开智能模式&#xff0c;那内存占用刷一下就上去了&#xff0c;没个3…

Apache Atlas(1):Atlas 入门

1 Atlas 概述 Apache Atlas 为组织提供开放式元数据管理和治理功能&#xff0c;用以构建其数据资产目录&#xff0c;对这些资产进行分类和管理&#xff0c;形成数据字典。并为数据分析师和数据治理团队&#xff0c;提供围绕这些数据资产的协作功能。 注&#xff1a;数据字典&…

SpringBoot3 integrate SpringDoc

SpringDoc 官方文档 Springdoc3取代swagger2 pom xml加载Springdoc JarOpenAPIDefinition&#xff0c;声明一个OpenAPI对API进行分组&#xff0c;方便查询访问地址springdoc ConfigurationRequestMapping pom xml加载Springdoc Jar <dependency><groupId>org.sprin…

记录idea插件wl spring assistant plugin的坑-不提示配置项,显示黑树叶

某一天在编写springboot项目的配置文件是&#xff0c;提示我按照插件wl spring assistant。 然后手贱&#xff0c;就安装了。 等第二天在编写配置文件的时候&#xff0c;就遇到了大坑&#xff0c;配置文件无法提示了。 正常情况下&#xff1a; 比如我们输入mybatis-plus的log&a…

mmpose----AnimalKingdom数据集使用mmpose训练

本文主要讲述了使用mmpose训练AnimalKingdom数据集来预测鸟类骨架 1、下载mmpose&#xff0c;AnimalKingdom数据集补充代码 安装 — MMPose 1.0.0 文档根据官方文档安装mmpose可以跑通demo GitHub - sutdcv/Animal-Kingdom: [CVPR2022] Animal Kingdom: A Large and Diverse…

自动化渗透测试自动化挖掘src

文章目录 前言思路资产收集资产收集http服务自动攻击利用 前言 好久没有写blog了&#xff0c;最近在上班干活&#xff0c;最近抽空研究了一下自动化渗透测试&#xff0c;下面分享一下 思路 资产收集 传统的资产收集都是跟域名挂钩&#xff0c;域名收集的好坏也至关重要&…

键盘敲入 A 字母时,操作系统期间发生了什么?

键盘可以说是我们最常使用的输入硬件设备了&#xff0c;但身为程序员的你&#xff0c;你知道「键盘敲入A 字母时&#xff0c;操作系统期间发生了什么吗」&#xff1f; 设备控制器 我们的电脑设备可以接非常多的输入输出设备&#xff0c;比如键盘、鼠标、显示器、网卡、硬盘、打…

ERP与WMS有哪些区别和联系?

一、什么是ERP ERP&#xff08;Enterprise Resource Planning&#xff09;是企业资源计划系统&#xff0c;它是一套综合的管理软件系统&#xff0c;可以帮助企业对各种业务管理、生产制造、供应链、销售财务等进行管理和优化。ERP系统的核心功能包括人力资源管理、物料管理、财…

无线电相关的SCI期刊有哪些? - 易智编译EaseEditing

以下是几个无线电相关的SCI期刊&#xff1a; IEEE Transactions on Wireless Communications&#xff1a; 这是一个IEEE无线通信协会的期刊&#xff0c;主要涵盖了无线通信领域的最新研究进展&#xff0c;包括无线网络&#xff0c;通信系统和信号处理等方面。 IEEE Transacti…

IntelliJ Platform-Plugins-获取鼠标选中字段或方法(PsiElement抽象)

PsiElement接口是文件中光标所在的那个字段&#xff0c;或者光标所在的那个方法的抽象&#xff0c;例如下图中&#xff0c;PsiElement就是private String name 而下图中PsiElement就是public String getName() 下面的代码会演示&#xff1a;光标在方法上&#xff0c;就打印方…

HTMLCSS

1、HTML 1.1 介绍 HTML 是一门语言&#xff0c;所有的网页都是用HTML 这门语言编写出来的&#xff0c;也就是HTML是用来写网页的&#xff0c;像京东&#xff0c;12306等网站有很多网页。 这些都是网页展示出来的效果。而HTML也有专业的解释 HTML(HyperText Markup Language)…

【EKF】卡尔曼滤波原理

前言 本篇是最近在学习云台以及姿态融合时&#xff0c;想学习一下卡尔曼滤波的原理&#xff0c;基于 DR_CAN 老师的卡尔曼滤波的视频做的笔记&#xff0c;基本上是按照 DR_CAN 老师的思路自己推导计算了一遍&#xff0c;推荐还是看一下原视频&#xff0c;讲解得很不错&#xf…

5款写作神器,帮助你写出5w+爆款文案,好用到哭

我不允许还有文案小白、新手博主不知道这5款写作利器&#xff01; 每次一写文案就头秃的新媒体工作者&#xff0c;赶紧看过来吧&#xff01;这5款好用到爆的写作神器&#xff0c;喝一杯咖啡的时间就能完成写作。 我和同事都是用它们&#xff0c;出了很多的爆款&#xff0c;现…

shell脚本--函数

目录 一&#xff1a;shell函数定义 1.函数的含义 2.函数的优点 3.函数的格式 4.函数返回值 &#xff08;1&#xff09;return输出 &#xff08;2&#xff09;echo输出 二&#xff1a;函数传参 1.情景一 2.情景二 3.情景三 4.情景四 三:递归函数 1.递归函数定义 2.通过…

STM32F103ZET6驱动TOF250激光测距传感器

STM32驱动TOF250激光测距传感器 TOF250介绍I2C通讯协议I2C寄存器地址 TOF250引脚说明和STM32的接线和STM32的接线 程序实验结果总结 TOF250介绍 TOF250是一款基于TOF原理的单点测距雷达&#xff0c;采用940nm红外光源&#xff0c;提供了精确和可重复的远 距离测量用于高速自动对…

OceanBase写入限速源码解读

一、简介 OceanBase中的写入限速机制旨在控制系统中写入操作&#xff08;一般写入操作包括插入、更新和删除等&#xff09;的速率&#xff0c;目的是为了提高数据库系统的稳定性。本文主要通过以下2个参数来解释写入限速的实现机制。 **1.**writing_throttling_trigger_perce…

MySQL-----索引特性

文章目录 前言一、没有索引,可能会有什么问题二、认识磁盘MySQL与存储先来研究一下磁盘在看看磁盘中一个盘片扇区结论磁盘随机访问(Random Access)和连续访问(Sequential Access) 三、MySQL与磁盘交互的基本单位四、建立共识五、索引的理解建立测试表插入多条记录查看插入结果中…

程序员最终会被自己开发的轮子所淘汰吗?

螺丝刀和扳手的发明&#xff0c;并没有让工人下岗&#xff1b; 工程机械&#xff08;挖掘机等&#xff09;的发明&#xff0c;也不会让建筑工人的需求量减少&#xff1b; 现代医学的各种先进设备&#xff0c;似乎也没有让医生数量大幅减少&#xff1b; …… 所以&#xff0c;关…

【团购-自定义Cell完善 Objective-C语言】

一、我们刚才这么写,有一个问题, 1.CZGoodsCell *cell = [[NSBundle mainBundle] loadNibNamed:@“CZGoodsCell” owner : nil options : nil ] ; 这样是不是没有进行单元格重用啊, 没有重用单元格, 我们说,前面还有一个对单元格进行重用吧, static NSString *ID = @“…