15_SpringBoot

文章目录

  • SpringBoot
    • 创建SpringBoot应用
      • 官网
      • IDEA
      • pom.xml文件
      • 启动类
    • 整合SpringMVC
      • 整合配置类
      • 静态资源处理
      • Filter
      • Tomcat
      • 其他配置
    • 整合MyBatis
    • 约定大于配置的原理
      • 配置文件中的值的获取
      • yml形式的配置文件
      • 约定大于配置的说明
      • 注解
      • 配置文件配置项

SpringBoot

  • SpringBoot简化Spring阶段的配置繁琐的工作
    • 快速搭建一个独立的生产级别的Spring应用
    • 快速引入项目相关依赖
    • 开箱即用,约定大于配置,大多数应用只需要极少的Spring配置
    • 内置JavaEE容器(内置了Tomcat),可以以jar包的方式启动
    • 核心点约定大于配置
      • 提供一些约定项(其实就是默认值),在应用程序启动过程中,向容器中注册默认组件

创建SpringBoot应用

官网

  • https://start.spring.io/
  • 选择groupId、ArtifactId、版本号、扫描包、JDK版本、项目构建方式、开发语言、引入的其他依赖来创建SpringBoot应用
  • 点击Generate会下载一个zip压缩包,解压开就是一个SpringBoot应用,同时也是一个Maven工程
    在这里插入图片描述

IDEA

  • 基本配置
    在这里插入图片描述
    在这里插入图片描述

pom.xml文件

  • 引入的依赖中,artifactid中有一个starter这样的一个词,这样的依赖就叫其starter依赖
    • spring-boot-starter
      • SpringBoot本身的依赖,所有的SpringBoot应用都有这个依赖
  • spring-boot-starter-xxx
    • SpringBoot官方提供的依赖(groupid → org.springframework.boot),提供的是SpringBoot对xxx技术的支持
      • 比如spring-boot-starter-web 就是SpringBoot对web技术的支持
      • 比如spring-boot-starter-tomcat就是SpringBoot对Tomcat的支持
      • 比如spring-boot-starter-json 就是SpringBoot对Json的支持
  • xxx-spring-boot-starter 第三方框架提供的依赖,提供的是SpringBoot对xxx技术的支持
    • 比如mybatis-spring-boot-starter,SpringBoot对MyBatis技术的支持
    • 比如pagehelper-spring-boot-starter
  • 通常在SpringBoot中要使用某一项技术,只需要引入其starter依赖就可以了
  • 为什么引入其starter依赖就可以了
    • starter依赖中关联了其他依赖,当我们引入starter依赖的时候,会将该技术所需要的其他的依赖一同引入进来
      • 举个例子:使用mybatis的话,引入mybatis-spring-boot-starter,mybatis、mybatis-spring、spring-jdbc都会被引入进来
    • starter依赖中通常会包含另外一个依赖autoconfigure依赖
      • autoconfigure依赖能够帮我们做自动配置,自动配置里最主要的是自动注册默认的组件

启动类

  • SpringBoot应用最终打包为Jar包,packaging的默认值也是jar
  • 运行jar包的命令
java -jar frontend.jar
  • 执行的jar包的main方法
Start-Class: com.coo1heisenberg.frontend.FrontendApplication
  • 启动类:main方法所处的类 → 启动类的包目录就是SpringBoot应用默认的扫描包目录

整合SpringMVC

  • spring-boot-starter-web

整合配置类

  • 配置类在SpringBoot阶段是可以使用的,但是有些内容产生了变化
    • 不需要写扫描包目录了 → springboot提供的默认的扫描包目录:启动类所在的包目录
    • 在配置类上增加@EnableWebMvc@Configuration
      • 如果使用@EnableWebMvc意味着全面接管SpringMVC的相关配置,默认配置失效
      • 如果使用**@Configuration**意味着做的是配置项的补充 → 建议使用

eg:

// @EnableWebMvc
// @ComponentScan("")
/**
 * 默认扫描包是启动类所在的包目录
 */
@Configuration
/**
 * @Configuration:配置项的增量补充,存量(默认配置)是自动配置
 *
 * @EnableWebMvc:全面接管SpringMVC的配置,默认配置失效 → 通常不全面接管
 */
public class WebConfiguration implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    }
}


静态资源处理

  • WebMvcConfigurer接口中的addResourceHandlers(registry)
  • registry.addResourceHandler("映射范围").addResourceLocations("静态资源所处的位置")
  • 上面这种方式可以在配置类中使用
  • SpringBoot也给我们做了默认的配置
    • mapping映射范围:/**
    • location资源所处的位置:classpath:/public/classpath:/static/classpath:/META-INF/
  • SpringBoot给我们提供了默认配置使用的是默认值;我们仍然可以使用其默认的配置,我们可以指定自定义的值
  • 自定义的配置
    • 配置文件是.propertieskey=value
    • 通过指定的key提供value,SpringBoot可以自动读取这些key对应的值

eg:

# http://localhost:8080/pic/1.jpg
# http://localhost:8080/pic/2.jpg

# path
spring.web.resources.static-locations=file:d:/test_photo/ 
# 文件路径
spring.mvc.static-path-pattern=/pic/**
# 执行 registry.addResourceHandler("映射范围").addResourceLocations("静态资源所处的位置")
# 会自动读取这两个值

总结

  • 静态资源处理
    • 啥都不做采用默认值
    • 配置文件中按照指定的key来提供对应的值
    • 也可以写配置类

在这里插入图片描述


Filter

  • 仍然可以使用OncePerRequestFilter使用Filter直接将其注册为容器中的组件就会生效

eg:

@Component
public class CustomFilter extends OncePerRequestFilter {
    @Autowired
    XXXService xxxService;
    
    @Autowired
    XXXMapper xxxMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("servlet执行之前");
        filterChain.doFilter(request, response);
    }
}
  • 好处:配置起来方便;也可以使用容器中的其他组件
  • HandlerInterceptor还是配置类的配置方式 → addInterceptors方法

eg:

public class WebConfiguration implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

    }
}

Tomcat

  • 端口号:server.port
  • 上下文路径:server.servlet.context-path

eg:

# Tomcat配置
server.port=8080
server.servlet.context-path=/demo1

其他配置

  • 配置类
  • 配置文件
    • prefix(前缀)为:spring.web
    • prefix(前缀)为:spring.mvc
    • 早期的一些SpringBoot版本:spring.resources → 它现在变了 spring.web.resources
  • jackson的一些配置:

eg:

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
# 时区信息
spring.jackson.time-zone=GMT+8 

整合MyBatis

  • 引入依赖
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.47</version>
</dependency>
  • 提供配置项的值
    • SpringBoot会根据这些默认向容器中注册DataSource组件的type:HikariCP( 默认的连接池)
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
  • 如果使用druid连接池,要使用全限定类名
# 将数据源修改为了Druid
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
  • 需要提供:Mapper接口的包目录
    • @MapperScan → 写在启动类上就行
@MapperScan("com.coo1heisenberg.demo1.mapper")
@SpringBootApplication
public class Demo1WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(Demo1WebApplication.class, args);
    }

}

约定大于配置的原理

配置文件中的值的获取

  • 现在自己向容器中注册一个DataSource,想把driverClassName、url、username、password这样的一些值写在配置文件中
  1. 没有从配置文件中取值
@Configuration
public class DataSourceConfiguration1 {

    /**
     * 魔法值:Magic value
     * 指的是写死了的值,不能修改
     */
    String driverClassName = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8";
    String userName = "root";
    String password = "123456";
    @Bean
    public DataSource dataSource1() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        return dataSource;
    }
}
  1. @Value
    • ${} 引用配置文件中的值,给@Value注解对应的成员变量赋值
    • 注意事项:在容器中的组件中才可以使用@Value
@Configuration
public class DataSourceConfiguration2 {

    /**
     * SpEL(Spring Expression Language)写法
     */
    @Value("${coo1heisenberg.datasource.driver-class-name}")
    String driverClassName; // = "com.mysql.jdbc.Driver";
    @Value("${coo1heisenberg.datasource.url}")
    String url; // = "jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8";
    @Value("${coo1heisenberg.datasource.username}")
    String userName; // = "root";
    @Value("${coo1heisenberg.datasource.password}")
    String password; // = "123456";
    @Bean
    public DataSource dataSource2() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        return dataSource;
    }
}
coo1heisenberg.datasource.driver-class-name=com.mysql.jdbc.Driver
coo1heisenberg.datasource.url=jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8
coo1heisenberg.datasource.username=root
coo1heisenberg.datasource.password=123456
  1. @ConfigurationProperties
    • 使用set方法给成员变量赋值
    • 注意事项:在容器中的组件中才可以使用
    • @ConfigurationProperties仍然是从配置文件中根据key来获得对应的值
      • key=@ConfigurationProperties注解的prefix属性值 + 成员变量名
@Configuration
@Data
@ConfigurationProperties(prefix = "coo1heisenberg.datasource3")
public class DataSourceConfiguration3 {
    
    String driverClassName; // = "com.mysql.jdbc.Driver";

    String url; // = "jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8";

    String userName; // = "root";

    String password; // = "123456";

    @Bean
    public DataSource dataSource3() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        return dataSource;
    }
}
coo1heisenberg.datasource3.driver-class-name=com.mysql.jdbc.Driver
coo1heisenberg.datasource3.url=jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8
coo1heisenberg.datasource3.username=root
coo1heisenberg.datasource3.password=123456
  1. @EnableConfigurationProperties和@ConfigurationProperties
    • 只有Properties组件注册过程有差别,其他的均一致
    • @EnableConfigurationProperties注解写在配置上,其value属性写的Class数组,将Class数组对应的类注册为容器中的组件

eg:

@ConfigurationProperties(prefix = "coo1heisenberg.datasource4")
@Data
public class DataSourceProperties4 {
    String driverClassName; // = "com.mysql.jdbc.Driver";

    String url; // = "jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8";

    String userName; // = "root";

    String password; // = "123456";
}
@Configuration
@EnableConfigurationProperties(DataSourceProperties4.class)
public class DataSourceConfiguration4 {

//    @Autowired
//    DataSourceProperties4 dataSourceProperties4;

    DataSourceProperties4 dataSourceProperties4;
    public DataSourceConfiguration4(DataSourceProperties4 dataSourceProperties4) {
        this.dataSourceProperties4 = dataSourceProperties4;
    }
    @Bean
    public DataSource dataSource3() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(dataSourceProperties4.getDriverClassName());
        dataSource.setUrl(dataSourceProperties4.getUrl());
        dataSource.setUsername(dataSourceProperties4.getUserName());
        dataSource.setPassword(dataSourceProperties4.getPassword());
        return dataSource;
    }
}
coo1heisenberg.datasource4.driver-class-name=com.mysql.jdbc.Driver
coo1heisenberg.datasource4.url=jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode=true&characterEncoding=utf-8
coo1heisenberg.datasource4.username=root
coo1heisenberg.datasource4.password=123456

yml形式的配置文件

  • properties一样都是key=value形式的配置文件,只不过语法上有区别
  • 可以将前面的properties配置文件修改为yml配置文件
    1. 如果key是多级的,比如spring.datasource.driver-clsss-name ,这个就是3级,yml 要写 冒号、换行、空格缩进(几个空格都可以,但是同一级要对齐)
    2. 等于:yml 要写 冒号 空格
    3. 如果有相同的前缀,省略掉重复的前缀

eg:

spring:
  web:
    resources:
      static-locations: file:d:/test_photo/

  mvc:
    static-path-pattern: /pic/**

  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/coo1heisenberg?userUnicode:true&characterEncoding:utf-8
    username: root
    password: 123456

server:
  port: 8080

  servlet:
    context-path: /demo1

约定大于配置的说明

  • SpringBoot实现约定大于配置主要做的事情是帮我们注册一些默认的组件,而默认的组件是自动自动配置类来进行配置的
    • 自动配置类:主要加载的使用autoconfigure依赖中的**/META-INF/spring.factories**文件里提供了自动配置类的列表
    • 最近的几个版本的SpringBoot也提供了另外的一个位置的配置类:/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  • @EnableAutoConfiguration注解上有一个注解
    @Import({AutoConfigurationImportSelector.class})
    
    1. @Import注解可以直接写配置类Class → 把这个配置类注册为容器中的组件
    2. @Import注解写的Class实现了Selector接口 → selectImports方法,返回值String[] → 配置类的全限定类名
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware, ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {


    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 读取/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
      // 读取/META-INF/spring.factories 里的 org.springframework.boot.autoconfigure.EnableAutoConfiguration这个key对应的值
    }
}

注解

  • @ConditionalOnXXX → 满足XXX条件其他的注解生效
  • @ConditionalOnMissingXXX → 满足缺少XXX条件,其他的注解生效

eg:

// 应用程序中要引入对应的类 → 要有对应的依赖 → starter引入的
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})

// 容器中DataSource类型的组件只有一个
@ConditionalOnSingleCandidate(DataSource.class)

eg:

  • @Bean和@ConditionalOnMissingBean通常同时出现
    • 如果你没有注册组件,那么@Bean生效,注册默认组件
    • 如果你注册了组件,那么@Bean不会生效,就不会注册默认组件,以你注册的组件为准
    • 综上可以得约定大于配置
@Bean
@ConditionalOnMissingBean({TransactionManager.class})
    DataSourceTransactionManager transactionManager(Environment environment, DataSource dataSource, ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {
      DataSourceTransactionManager transactionManager = this.createTransactionManager(environment, dataSource);
      transactionManagerCustomizers.ifAvailable((customizers) -> {
        customizers.customize(transactionManager);
      });
      return transactionManager;
    }

	.....


配置文件配置项

  • 引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <version>2.7.10</version>
</dependency>
  • 这个依赖会帮我们新增对应的json
    • 生成之后,在resources目录下新增一个文件夹 META-INF

eg:

{
  "groups": [
    {
      "name": "coo1heisenberg.datasource3",
      "type": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3",
      "sourceType": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3"
    },
    {
      "name": "coo1heisenberg.datasource4",
      "type": "com.coo1heisenberg.demo2.config4.DataSourceProperties4",
      "sourceType": "com.coo1heisenberg.demo2.config4.DataSourceProperties4"
    }
  ],
  "properties": [
    {
      "name": "coo1heisenberg.datasource3.driver-class-name",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3"
    },
    {
      "name": "coo1heisenberg.datasource3.password",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3",
      "defaultValue": "123456"
    },
    {
      "name": "coo1heisenberg.datasource3.url",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3"
    },
    {
      "name": "coo1heisenberg.datasource3.user-name",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config3.DataSourceConfiguration3"
    },
    {
      "name": "coo1heisenberg.datasource4.driver-class-name",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config4.DataSourceProperties4"
    },
    {
      "name": "coo1heisenberg.datasource4.password",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config4.DataSourceProperties4"
    },
    {
      "name": "coo1heisenberg.datasource4.url",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config4.DataSourceProperties4"
    },
    {
      "name": "coo1heisenberg.datasource4.user-name",
      "type": "java.lang.String",
      "sourceType": "com.coo1heisenberg.demo2.config4.DataSourceProperties4"
    }
  ],
  "hints": []
}

在这里插入图片描述

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

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

相关文章

强化网络安全防线,您的等级保护措施到位了吗?

在这个信息化飞速发展的时代&#xff0c;网络安全已经成为我们每个人都需要关注的问题。无论是企业还是个人&#xff0c;我们的工作和生活都越来越依赖于网络。确保网络环境的安全&#xff0c;防止信息泄露和网络攻击&#xff0c;已经成为了一项至关重要的任务。等级保护制度作…

现货白银的止损:原始止损和移动止损

止损是我们做现货白银必备的工具&#xff0c;它的主要功能是控制投资者的亏损&#xff0c;进而控制我们在交易中的风险。而现货白银的止损主要有两种&#xff0c;一个是原始止损&#xff0c;另外一个是移动止损。 原始止损是我们现货白银止损的基本方法。原始止损的意思就是初次…

Git回滚版本并push到远端master

1、查看日志 git log 2、还原最近的版本 () --git reset --hard commit-id 如&#xff1a;git reset --hard d84da14bf2743683eca7a015f56114faaa344f42 3、覆盖分支版本 git push -f origin dev 回滚本地master完成后&#xff0c;将回滚后的代码push到远端master&#xf…

C++ | Leetcode C++题解之第25题K个一组翻转链表

题目&#xff1a; 题解&#xff1a; class Solution { public:// 翻转一个子链表&#xff0c;并且返回新的头与尾pair<ListNode*, ListNode*> myReverse(ListNode* head, ListNode* tail) {ListNode* prev tail->next;ListNode* p head;while (prev ! tail) {ListN…

C++练级之路——类和对象(中二)

1、运算符重载 C为了增强代码的可读性引入了运算符重载&#xff0c;运算符重载是具有特殊函数名的函数&#xff0c;也是具有其返回值类型&#xff0c;函数名字以及参数列表&#xff0c;其返回值类型和参数列表与普通的函数类似。 函数名字为&#xff1a;关键字operator后面接需…

华为ensp中静态路由和默认路由的原理及配置

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月17日17点37分 默认路由 [Router] ip route-static <目的网络> <目的网络掩码> <下一跳地址>默认路由的作用是将无法匹配路由表中其他路由表项的…

储能的全生命周期成本即平准化度电成本的计算方法及python实践

1. 平准化度电成本&#xff08;LCOE&#xff09;是一种衡量电力项目经济性的指标 LCOE&#xff08;Levelized Cost of Energy,&#xff09;的概念最早由美国国家可再生能源实验室&#xff08;NREL&#xff09;在1995年提出&#xff0c;它是通过将一个项目生命周期内的所有成本…

公司微信公众号怎么创建?

公众号已经成为企业、品牌、个人IP与粉丝互动的重要平台。今天&#xff0c;伯乐网络传媒就来深入探讨如何巧妙地创建属于自己的微信公众号&#xff0c;为公司或品牌打造一个线上影响力的坚实基石。 一、注册微信公众号 第一步&#xff1a;访问微信公众平台官网 第二步&#x…

27.5k star!微软开源的项目,他好像真的想教会你 AI【文末带源码】

AI 和机器学习&#xff08;ML&#xff09;的发展正在改变我们的世界&#xff0c;从智能助手到自动驾驶汽车&#xff0c;无所不在。对于我的读者朋友来说&#xff0c;大家肯定是多多少少的使用过各种 AI 工具。然而&#xff0c;AI 和 ML 背后的工作机制究竟是什么样的呢&#xf…

volatile

volatile&#xff1a; 用来声明变量的关键字之一&#xff0c;它的主要作用是确保多个线程能够正确地处理共享变量。在多线程编程中&#xff0c;如果一个变量被多个线程共享并且这些线程可能同时修改该变量的值&#xff0c;那么就需要使用 volatile 关键字来保证线程之间对该变量…

IPV6——缓解地址池枯竭

目录 一.IPV6的来源 二.关于IPV6 1.’无限‘的地址空间 2.简化报文头部 3.层次化结构设计 4.即插即用 5.安全特性 6.Qos特性 三.IP v4&#xff0c;IP v6报文头部 IP v4 重点—TTL&#xff08;Time to live&#xff09; —— 存活时间&#xff0c;用于三层防环&#…

二维码电子画册制作教程,教你如何做出高端作品!

当今社会&#xff0c;二维码已经成为了信息传递的重要方式之一&#xff0c;其在电子商务、广告营销、活动推广等领域广泛应用。而如何将二维码巧妙地融入电子画册中&#xff0c;制作出高端、具有吸引力的作品&#xff0c;成为了许多设计师和营销人员关注的焦点 但是很多人却不知…

K8s的亲和、反亲和、污点、容忍

1 亲和与反亲和 亲和性的原理其实很简单&#xff0c;主要利用label标签结合nodeSelector选择器来实现 1.1 Pod和Node 从pod出发&#xff0c;可以分成亲和性和反亲和性&#xff0c;分别对应podAffinity和podAntiAffinity。从node出发&#xff0c;也可以分成亲和性和反亲和性&…

FANUC机器人通过ROBOGUIDE实现与实际的机器人进行程序导入导出的具体方法示例

FANUC机器人通过ROBOGUIDE实现与实际的机器人进行程序导入导出的具体方法示例 如下图所示,在电脑的开始菜单中找到”Robot Neiborhood”,点击进入, 如下图所示,设置要连接的机器人名称和主机IP地址(要确保自己的电脑和机器人IP地址在同一网段内),点击Add添加, 添加在线…

[Qt网络编程]之获取基本网络信息

前言 获取主机的网络地址和接口信息是进行网络编程的第一步&#xff0c;也是网络编程的基础。Qt提供了网络接口类 QNetworkInterface、网络地址人口类 QNetworkAddressEntry 和主机地址类 QHostAddress 来获取和使用地址信息。其中网络接口类 QNetworkInterface 描述了主机的卫…

光电水位开关数字信号与模拟信号的区别

如今随着液位检测技术的不断发展&#xff0c;检测液位的方法也越来越多&#xff0c;在小家电领域应用最多的液位检测方法就是光电液位传感器&#xff0c;光电液位传感器分为数字信号和模拟信号两种&#xff0c;都是输出高低电压信号&#xff0c;但输出的电压不一样。 数字信号…

OJ 连续数的和 球弹跳高度的计算【C判断是否为完全平方数】【格式输出%g输出全部小数部分】

连续数的和 判断是否为完全平方数有两种方法 1.遍历所有小于该数的整数&#xff0c;有一个满足平方与该数相等&#xff0c;则是完全平方数 2.用sqrt()或pow()函数对该数开方&#xff0c;取整&#xff08;舍去小数部分&#xff09;&#xff0c;再平方&#xff0c;与该数相等则…

项目7-音乐播放器4

1.喜欢/收藏音乐模块设计 1.1 请求响应模块设计 请求&#xff1a; { post, /lovemusic/likeMusic data: id//音乐id } 响应&#xff1a; { "status": 0, "message": "点赞音乐成功", "da…

力扣:120. 三角形最小路径和

力扣&#xff1a;120. 三角形最小路径和 给定一个三角形 triangle &#xff0c;找出自顶向下的最小路径和。 每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 1 的两个结点。也就是说&#xff0c;如果正…

特殊文件-XML文件

简介 XML全称&#xff1a;Etensible Markup Language&#xff0c;可扩展标记语言 特点 标签都是成对出现的&#xff0c;一个标签就是一个元素一个xml文件中有且只有一个根标签标签也是可以携带属性的 IDEA创建XML 简单示例 必须有抬头标签是可以携带属性的&#xff0c;但是属性…
最新文章