当前位置: 首页 > news >正文

SpringBoot高级-底层原理

目录

1 SpringBoot自动化配置原理

01-SpringBoot2高级-starter依赖管理机制

02-SpringBoot2高级-自动化配置初体验

03-SpringBoot2高级-底层原理-@Configuration配置注解

04-SpringBoot2高级-底层原理-@Import注解使用1

05-SpringBoot2高级-底层原理-@Import注解使用2

06-SpringBoot2高级-底层原理-@Conditional衍生条件装配

07-SpringBoot2高级-底层原理-@ConfigurationProperties配置绑定

08-SpringBoot2高级-自动化配置原理-@SpringBootApplication入口分析

09-SpringBoot2高级-自动化配置原理-@EnableAutoConfiguration自动配置注解

10-SpringBoot2高级-自动化配置原理-按条件开启自动配置类和配置项

11-SpringBoot2高级-自动化配置原理-debug全流程

12-SpringBoot2高级-自动化配置原理-总结

2 SpringBoot健康监控

13-SpringBoot2高级-监控-健康监控服务

14-SpringBoot2高级-监控-Admin可视化


  • 理解SpringBoot自动化配置源码
  • 理解SpringBoot健康监控

1 SpringBoot自动化配置原理

01-SpringBoot2高级-starter依赖管理机制

目的:通过依赖能了解SpringBoot管理了哪些starter

讲解:

  1. 通过依赖 spring-boot-dependencies 搜索 starter- 发现非常多的官方starter,并且已经帮助我们管理好了版本。
  2. 项目中使用直接引入对应的 starter 即可,这个场景下需要的依赖就会自动导入到项目中,简化了繁琐的依赖。如果需要修改版本可以有两种方式:

  • 重写maven属性
  • 使用Maven依赖管理的就近原则

      3.引入 starter 不仅仅是帮助我们管理了依赖,还帮我做了很多的默认的配置信息,简化了大量的配置,使用更加的简单。

      4.所有的场景启动器的底层都依赖 spring-boot-starter

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.3.10.RELEASE</version><scope>compile</scope></dependency>

小结:

  • 引入官方starter依赖默认都可以不写版本
  • 如果配置满足您当前开发需要,则默认配置即可
02-SpringBoot2高级-自动化配置初体验

目的:以web MVC自动化配置原理为例讲解,能够理解web MVC自动化配置加入了哪些依赖,做了哪些默认配置。

讲解:

回忆一下:SpringMVC博文中,我们在 SSM整合时;

添加spring及spring web mvc相关依赖

springmvc配置类:

1、扫描controller层

2、静态资源控制

3、......

servlet容器配置类:

1、扫描springmvc配置类

2、扫描spring配置类

3、设置哪些请求交给springmvc处理

4、POST请求乱码过滤器

部署还需要单独的tomcat

也就是说:我们现在需要在开发业务代码前,就必须要准备好这些环境,否则无法完成业务代码,这就是我们现在的问题。

让这些问题成为过去,现在我们就探索一下SpringBoot是如何帮助我们完成强大而又简单自动化配置的。

引入 web 开发场景启动器依赖:

<!--web开发的起步依赖   场景启动器依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>

帮助我们做了以下自动化配置:

  1. 依赖版本和依赖什么jar都不需要开发者关注
  1. 自动化配置
  • 自动配好SpringMVC
    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(三大组件,文件上传等)
  • 自动配好Web常见功能,如:字符编码问题,静态资源管理
  1. 自动配好Tomcat

小结:

  • 有了SpringBoot以后,让开发人员重点关注业务本身,而不是环境上,提升了开发效率。
03-SpringBoot2高级-底层原理-@Configuration配置注解

目的:掌握@Configuration注解的作用及新特性

讲解:

1、@Configuration注解的作用是替代原始 spring配置文件 功能

演示:

1)编写配置类

package com.itheima.sh.config;import com.itheima.sh.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 1、@Configuration 替代 spring配置文件(配置bean)* 2、组件源码中包含 @Component 注解,当前类也会注册到 IOC 容器,默认类名小写* 3、默认都是单例的*/
@Configuration
public class MyConfig {@Bean   // 默认方法名称作为容器中的namepublic User getUser() {return new User();}
}

2)在引导类编写代码测试:

@SpringBootApplication
@MapperScan(basePackages = "com.itheima.sh.mapper")
public class DataApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DataApplication.class, args);// 根据name获取容器中的beanUser user1 = applicationContext.getBean("getUser", User.class);User user2 = applicationContext.getBean("getUser", User.class);System.out.println(user1 == user2);MyConfig myConfig1 = applicationContext.getBean("myConfig", MyConfig.class);MyConfig myConfig2 = applicationContext.getBean("myConfig", MyConfig.class);System.out.println(myConfig1 == myConfig2);// 注意:如果 MYConfig配置类没有按照规范编写,则容器中bean 的name为 类名}
}

SpringBoot 提供一个注解和当前注解功能一样:

@SpringBootConfiguration

2、proxyBeanMethods:代理bean的方法属性(since spring 5.2以后)

功能:

  • proxyBeanMethods = true:Full模式,保证每个@Bean方法被调用多少次返回的组件都是单实例的
  • proxyBeanMethods = false:Lite模式,每个@Bean方法被调用多少次返回的组件都是新创建的

演示:

  1. 默认 proxyBeanMethods=true,springBoot会检查这个组件是否在容器中有,有则直接引用
// 默认 proxyBeanMethods=true springBoot会检查这个组件是否在容器中有,有则直接引用
User user3 = myConfig1.getUser();
System.out.println(user1 == user3);  // true
  1. 修改 proxyBeanMethods=false,则每调用一次Spring就会创建一个新的Bean对象

在执行结果则为 false, 证明两次获取的bean不是同一个bean。

小结:

  • 组件依赖必须使用Full模式默认。
  • Full模式每次都会检查bean,效率较Lite模式慢
04-SpringBoot2高级-底层原理-@Import注解使用1

目的:能够理解@Import注解作用及4种使用方式

讲解:

作用:使用@Import导入的类会被Spring加载到IOC容器中

@Import提供4种用法:

  1. 导入Bean
  1. 导入配置类
  1. 导入 ImportSelector 实现类。一般用于加载配置文件中的类
  1. 导入 ImportBeanDefinitionRegistrar 实现类

实现:

1、导入Bean

package com.itheima.sh;import com.itheima.sh.pojo.User;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;import java.util.Map;@SpringBootApplication
@Import(User.class)  
//会自动执行当前类的构造方法创建对象,存到IOC容器, bean名称为:类的全路径public class DataApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DataApplication.class, args);Map<String, User> map = applicationContext.getBeansOfType(User.class);System.out.println(map);User user1 = applicationContext.getBean("com.itheima.sh.pojo.User", User.class);System.out.println(user1);}
}

2、导入配置类

package com.itheima.sh;import com.itheima.sh.config.MyConfig;
import com.itheima.sh.pojo.User;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;import java.util.Map;@SpringBootApplication
@MapperScan(basePackages = "com.itheima.sh.mapper")
//@Import(User.class)
//1、会自动执行当前类的构造方法创建对象,存到IOC容器, bean名称为:类的全路径@Import(MyConfig.class)
//2、创建MyConfig bean,并且类中有 带有@Bean注解方法,创建对象存到IOC容器,bean名称为:默认方法名称
public class DataApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DataApplication.class, args);//{getUser=com.itheima.sh.pojo.User@1b4a3a1}Map<String, User> map = applicationContext.getBeansOfType(User.class);System.out.println(map);User user1 = applicationContext.getBean("getUser", User.class);System.out.println(user1);Map<String, MyConfig> config = applicationContext.getBeansOfType(MyConfig.class);//{com.itheima.sh.config.MyConfig=com.itheima.sh.config.MyConfig@7e848aea}System.out.println(config);}
}

05-SpringBoot2高级-底层原理-@Import注解使用2

目的:讲解@Import注解使用另外两种使用方式

步骤:

  1. 导入 ImportSelector 实现类。一般用于加载配置文件中的类
  1. 导入 ImportBeanDefinitionRegistrar 实现类

实现:

导入 ImportSelector 实现类。一般用于加载配置文件中的类

1、编写 ImportSelector 实现类,MyImportSelector

2、引导类导入

package com.itheima.sh;import com.itheima.sh.config.MyImportSelector;
import com.itheima.sh.pojo.User;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;import java.util.Map;@SpringBootApplication
@MapperScan(basePackages = "com.itheima.sh.mapper")
//@Import(User.class)
//1、会自动执行当前类的构造方法创建对象,存到IOC容器, bean名称为:类的全路径//@Import(MyConfig.class)
//2、创建MyConfig bean,并且类中有 带有@Bean注解方法,创建对象存到IOC容器,bean名称为:默认方法名称@Import(MyImportSelector.class)
//3、创建MyConfig bean 名称为:类名全路径,创建带有@Bean注解方法实例,名称为:方法名称
public class DataApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DataApplication.class, args);Map<String, MyConfig> map = applicationContext.getBeansOfType(MyConfig.class);//{com.itheima.sh.config.MyConfig=com.itheima.sh.config.MyConfig@44384b4a}System.out.println(map);Map<String, User> userMap = applicationContext.getBeansOfType(User.class);//{getUser=com.itheima.sh.pojo.User@5cc3e49b}System.out.println(userMap);}
}

导入 ImportBeanDefinitionRegistrar 实现类

1、编写 ImportBeanDefinitionRegistrar 实现类,MyImportBeanDefinitionRegistrar

package com.itheima.sh.config;import com.itheima.sh.pojo.User;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** @param importingClassMetadata 导入类的元注解信息* @param registry Bean注册表*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();registry.registerBeanDefinition("user", beanDefinition);}
}

2、引导类测试

package com.itheima.sh;import com.itheima.sh.config.MyImportBeanDefinitionRegistrar;
import com.itheima.sh.pojo.User;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;import java.util.Map;@SpringBootApplication
@MapperScan(basePackages = "com.itheima.sh.mapper")//@Import(User.class)
//1、会自动执行当前类的构造方法创建对象,存到IOC容器, bean名称为:类的全路径//@Import(MyConfig.class)
//2、创建MyConfig bean,并且类中有 带有@Bean注解方法,创建对象存到IOC容器,bean名称为:默认方法名称//@Import(MyImportSelector.class)
//3、创建MyConfig bean 名称为:类名全路径,创建带有@Bean注解方法实例,名称为:方法名称@Import(MyImportBeanDefinitionRegistrar.class)
//4、创建Bean,名称:在registerBeanDefinition中定义
public class DataApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(DataApplication.class, args);Map<String, User> userMap = applicationContext.getBeansOfType(User.class);//{user=com.itheima.sh.pojo.User@23c7cb18}System.out.println(userMap);}
}

小结:

  • 讲解当前小节的目的主要是为源码准备
  • 还有我们也可以知道创建Bean对象,还可以使用@Import四种方式

06-SpringBoot2高级-底层原理-@Conditional衍生条件装配

目的:理解@Conditional衍生条件装配的作用

讲解:

作用:条件装配,满足Conditional指定的条件,则进行组件注入,初始化Bean对象到IOC容器

演示:

在RedisConfig类中添加注释:

方法中定义:

类上定义:

注意:也可以添加到 类上, 满足条件则类及类中的对象生效。

小结:

  • @ConditionalOnXXX 注解存在的意义是:满足条件当前类或者Bean才有效,按需导入。
07-SpringBoot2高级-底层原理-@ConfigurationProperties配置绑定

目的:

回顾 @ConfigurationProperties配置绑定 存在的目的是:获取配置属性或者是配置文件指定前缀的属性信息,并且初始化Bean对象到 IOC 容器。

由此我们可以想:将来的配置我们可以放在配置文件中,通过这个注解来读取并封装成对象

08-SpringBoot2高级-自动化配置原理-@SpringBootApplication入口分析

目的:能够理解SpringBoot自动化配置流程中@SpringBootApplication是一个组合注解,及每一个注解的作用能够知道作用。

讲解:

1、SpringBoot是一个组合注解

2、@SpringBootConfiguration注解作用

  • @SpringBootConfiguration是对@Configuration注解的包装,proxyBeanMethods 默认配置 true, full模式(单例Bean)
  • 标识是一个配置类,所以 引导类也是配置类

3、@ComponentScan注解作用

  • 组件扫描,默认扫描的规则 引导类所在的包及其子包所有带注解的类

问题:

  1. 在引导类中配置 @Bean 注解可以吗?
  1. 为什么Controller、service类添加完注解后,不需要添加扫描包?

09-SpringBoot2高级-自动化配置原理-@EnableAutoConfiguration自动配置注解

目的:理解@EnableAutoConfiguration自动化配置核心实现注解

讲解:

1、@EnableAutoConfiguration是一个组合注解

2、@AutoConfigurationPackage注解作用

作用:利用Registrar给容器中导入一系列组件

点击 Registrar 进入到源码的 register 方法,添加 断点,测试

通过 debug 程序发现,默认情况下 将引导类的所有包及其子包的组件导入进来

3、@Import(AutoConfigurationImportSelector.class)注解作用

作用:是利用selectImports方法中的 getAutoConfigurationEntry 方法给容器中批量导入相关组件

调用流程分析:

  1. 调用AutoConfigurationImportSelector类中的selectImports方法
  1. 调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
  1. 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader)得到所有的组件
  1. 从META-INF/spring.factories位置来加载一个文件。 默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件

spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

通过这个配置文件加载的自动配置:当前版本(2.3.10)是有127个默认的自动化配置

小结:

  • 自动化配置默认加载的配置文件在哪?
10-SpringBoot2高级-自动化配置原理-按条件开启自动配置类和配置项

目的:

  • 能够理解所有的自动化配置虽然会全部加载,底层有大量的@ConditionalOnXXX,有很多自动配置类并不能完全开启。
  • 如果配置生效了,则会加载默认的属性配置类,实现默认的对应场景的自动化配置

讲解:

1、以上通过 META-INF/spring.factories 配置文件找到所有的自动化配置类,但 是不是全部的生效的呢?很显然是不可能全部都生效的。

2、以 JdbcTemplateAutoConfiguration 为例讲解, 进入到 JdbcTemplateAutoConfiguration 自动化配置类。

//配置类,Lite模式
@Configuration(proxyBeanMethods = false)
//存在 DataSource、JdbcTemplate 类时再加载当前类
@ConditionalOnClass({DataSource.class, JdbcTemplate.class })//容器中只有一个指定的Bean,或者这个Bean是首选Bean 加载当前类
@ConditionalOnSingleCandidate(DataSource.class)//在配置类 DataSourceAutoConfiguration 之后执行
@AutoConfigureAfter(DataSourceAutoConfiguration.class)//如果条件满足:开始加载自动化配置的属性值 JdbcProperties
@EnableConfigurationProperties(JdbcProperties.class)@Import({JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class })
public class JdbcTemplateAutoConfiguration {}

3、JdbcProperties,用于加载默认的配置,如果配置文件配置了该属性,则配置文件就生效。

4、通过@Import导入JdbcTemplateConfiguration

//配置类,Lite模式
@Configuration(proxyBeanMethods = false)
//没有JdbcOperations类型的bean时加载当前类,而 JdbcTemplate 是 JdbcOperations 接口实现类
@ConditionalOnMissingBean(JdbcOperations.class)
class JdbcTemplateConfiguration {@Bean@PrimaryJdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);JdbcProperties.Template template = properties.getTemplate();jdbcTemplate.setFetchSize(template.getFetchSize());jdbcTemplate.setMaxRows(template.getMaxRows());if (template.getQueryTimeout() != null) {jdbcTemplate.setQueryTimeout((int) template.getQueryTimeout().getSeconds());}return jdbcTemplate;}}

验证:我们可以在我们自己的项目里面创建一个 JdbcTemplate Bean,看容器创建的Bean执行的是哪一个方法。

@Configuration
public class MyConfig {@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource){JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);System.out.println("自定义 JdbcTemplate");return jdbcTemplate;}
}

结果:保证容器中只有一个 Bean 实例

问题:

  • 这些不用的 starter 的依赖,能不能导入到我们工程里面? 为什么?
11-SpringBoot2高级-自动化配置原理-debug全流程

目的:能够理解整个SpringBoot启动的完成自动化配置及属性加载的全过程

12-SpringBoot2高级-自动化配置原理-总结

SpringBoot自动化配置流程总结:

  • 程序启动找到自动化配置包下 META-INF/spring.factoriesEnableAutoConfiguration
  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效。
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

开发人员使用步骤总结:

  • 引入场景依赖
  • 查看自动配置了哪些(选做)
    • 自己分析,引入场景对应的自动配置一般都生效了
    • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
  • 自己分析是否需要修改
  • 参照文档修改配置项,xxxxProperties绑定了配置文件的哪些。
    • 自定义加入或者替换组件,@Bean、@Component等

2 SpringBoot健康监控

13-SpringBoot2高级-监控-健康监控服务

目的:能够理解健康监控actuator的作用

讲解:

每一个微服务在云上部署以后,我们都需要对其进行监控、追踪、审计、控制等。SpringBoot就抽取了Actuator场景,使得我们每个微服务快速引用即可获得生产级别的应用监控、审计等功能。

实现:

1、引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>

2、启动项目,访问 http://localhost:80/actuator

3、暴露所有监控信息为HTTP

management:endpoints:enabled-by-default: true #暴露所有端点信息web:exposure:include: '*'  #以web方式暴露endpoint:health:enabled: true   # 开启健康检查详细信息show-details: always

访问 http://localhost:80/actuator 会发现内容多了,里面的地址分别都可以访问,记录的是对应的健康监测的信息。

14-SpringBoot2高级-监控-Admin可视化

目的:能够搭建 可视化监控平台

讲解:

SpringBoot Admin 有两个角色,客户端(Client)和服务端(Server)。

Spring Boot Admin为注册的应用程序提供以下功能:

  • 显示健康状况
  • 显示详细信息,例如
    • JVM和内存指标
    • micrometer.io指标
    • 数据源指标
    • 缓存指标
  • 显示内部信息
  • 关注并下载日志文件
  • 查看JVM系统和环境属性
  • 查看Spring Boot配置属性
  • 支持Spring Cloud的可发布/ env-和// refresh-endpoint
  • 轻松的日志级别管理
  • 与JMX-beans交互
  • 查看线程转储
  • 查看http-traces
  • 查看审核事件
  • 查看http端点
  • 查看预定的任务
  • 查看和删除活动会话(使用spring-session)
  • 查看Flyway / Liquibase数据库迁移
  • 下载heapdump
  • 状态更改通知(通过电子邮件,Slack,Hipchat等)
  • 状态更改的事件日志(非持久性)

快速入门:Spring Boot Admin Reference Guide

实现:

以下为创建服务端和客户端工程步骤:

搭建Server端:

1、创建 admin_server 模块,引入依赖

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.10.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent><dependencies><dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.3.1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>

2、开启注解支持

package com.itheima.sh;import de.codecentric.boot.admin.server.config.EnableAdminServer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@EnableAdminServer
public class AdminApplication {public static void main(String[] args) {SpringApplication.run(AdminApplication.class, args);}
}

注意端口修改为:9999

搭建Client端:

1、在任意服务里面引入依赖

<dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-client</artifactId><version>2.3.1</version></dependency>

2、配置文件

  # 执行admin.server地址
spring:   boot:admin:client:url: http://localhost:9999  # admin 服务地址instance:prefer-ip: true   # 显示IPapplication:name: boot_data  # 项目名称management:endpoints:enabled-by-default: true #暴露所有端点信息web:exposure:include: '*'  #以web方式暴露endpoint:health:enabled: true   # 开启健康检查详细信息show-details: always

3、启动服务,访问admin Server http://localhost:9999/

 

相关文章:

SpringBoot高级-底层原理

目录 1 SpringBoot自动化配置原理 01-SpringBoot2高级-starter依赖管理机制 02-SpringBoot2高级-自动化配置初体验 03-SpringBoot2高级-底层原理-Configuration配置注解 04-SpringBoot2高级-底层原理-Import注解使用1 05-SpringBoot2高级-底层原理-Import注解使用2 06-S…...

LabVIEW提高开发效率技巧----插入式架构

随着LabVIEW项目规模的扩大和系统复杂性的增加&#xff0c;传统的单一代码架构难以应对后期维护和功能扩展的需求。插入式架构&#xff08;Plug-In Architecture&#xff09;作为一种模块化设计方式&#xff0c;通过动态加载和运行子VI&#xff0c;使系统功能更加灵活、模块化&…...

MySQL COUNT(*)、COUNT(1)、COUNT(id)、COUNT(字段)效果及性能

文章目录 前言COUNT(exper)COUNT(*)优化COUNT(*) 与COUNT(1) COUNT(1)COUNT(id)COUNT(字段)总结参考 前言 业务开发中&#xff0c;我们经常要使用count做一些数据统计。今天根据MySQL5.7官方文档及丁奇老师的MySQL45讲&#xff0c;介绍一下COUNT(*)、COUNT(1)、COUNT(id)、COU…...

webpack4 - 动态导入文件 dynamic-import 报错的解决方法

介绍 webpack4动态导入文件报错&#xff0c;按照错误提示安装了插件&#xff0c;但未果。。 最后查到一个可行方案&#xff0c;记录如下。 1.通过懒加载的方式动态引入文件 const router new Router({routes: [{path: /home,name: Home,component: () >import(./views/h…...

【NodeJS】NodeJS+mongoDB在线版开发简单RestfulAPI (四):状态码的使用

本项目旨在学习如何快速使用 nodejs 开发后端api&#xff0c;并为以后开展其他项目的开启提供简易的后端模版。&#xff08;非后端工程师&#xff09; 由于文档是代码写完之后&#xff0c;为了记录项目中需要注意的技术点&#xff0c;因此文档的叙述方式并非开发顺序&#xff0…...

springboot061基于B2B平台的医疗病历交互系统(论文+源码)_kaic

摘 要 进入21世纪&#xff0c;计算机技术迅速向着网络化的、集成化方向发展。传统的单机版应用软件正在逐渐退出舞台&#xff0c;取而代之的是支持网络、支持多种数据信息的新一代网络版应用软件&#xff0c;形成了信息化的社会。信息化社会的形成和微电子技术日新月异的发展&…...

基于FFT + CNN -Transformer时域、频域特征融合的电能质量扰动识别模型

往期精彩内容&#xff1a; Python-电能质量扰动信号数据介绍与分类-CSDN博客 Python电能质量扰动信号分类(一)基于LSTM模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(二)基于CNN模型的一维信号分类-CSDN博客 Python电能质量扰动信号分类(三)基于Transformer的一…...

JAVA开发环境:IntelliJ IDEA、Java JDK、Maven 安装配置

一、安装IntelliJ IDEA 准备安装包 通过百度网盘分享的文件&#xff1a;idea2023.2U**.zip 链接&#xff1a;https://pan.baidu.com/s/1NB04A-jMXhZKsewYshGt-Q 提取码&#xff1a;oeft 安装 IntelliJ IDEA &#xff08;1&#xff09;、解压&#xff0c;安装文件如下&#…...

鸿蒙软件开发中常见的如何快速自动生成二维码?QRCode组件

QRCode 用于显示单个二维码的组件。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 二维码组件的像素点数量与内容有关&#xff0c;当组件尺寸过小时&#xff0c;可能出现无法展示内容的情况&…...

鸿蒙HarmonyOS NEXT 5.0开发(2)—— ArkUI布局组件

文章目录 布局Column&#xff1a;从上往下的布局Row&#xff1a;从左往右的布局Stack&#xff1a;堆叠布局Flex&#xff1a;自动换行或列 组件Swiper各种选择组件 华为官方教程B站视频教程 布局 主轴和交叉轴的概念&#xff1a; 对于Column布局而言&#xff0c;主轴是垂直方…...

【openGauss】OPENGAUSS/POSTGRESQL 中float类型到int类型的隐式转换

下面这条sql在oracle和POSTGRESQL/OPENGAUSS中的查询结果不一致 select cast(cast(0.5 as float) as integer);在oracle中返回1&#xff0c;在openGauss中返回0&#xff0c;咋一看好像是openGauss中使用了截断的方式,但是如果执行 select cast(cast(1.5 as float) as integ…...

Docker:安装 Syslog-ng 的技术指南

1、简述 Syslog-ng 是一种流行的日志管理工具&#xff0c;能够集中处理和分析日志。通过 Docker 安装 Syslog-ng 可以简化部署和管理过程。本文将介绍如何使用 Docker 安装 Syslog-ng&#xff0c;并提供一个 Java 示例来展示如何将日志发送到 Syslog-ng。 2、安装 2.1 创建…...

即插即用的3D神经元注意算法!

本文所涉及所有资源均在 传知代码平台 可获取。 目录 3D神经元注意力&#xff1a;为每一个神经元分配权重&#xff01;&#xff08;算法&#xff09; 一、概述 二、研究背景 三、主要贡献 四、模型结构和代码 五、数据集介绍 六、性能展示 六、复现过程 七、运行过程 SimAM总结…...

FPGA 蜂鸣器 音乐播放器

点击&#xff1a; FPGA 蜂鸣器音乐播放器 基于FPGA的beep音乐播放器设计 FPGA&#xff08;Field Programmable Gate Array&#xff09;蜂鸣器音乐播放器是一个将FPGA编程用于控制蜂鸣器播放音乐的设备。下面是一个简单的实现步骤和思路&#xff1a; 一、硬件准备 FPGA开发板…...

前端-基础CSS总结常用

1.书写位置:title 标签下方添加 style 双标签,style 标签里面书写 CSS 代码。 <title>CSS 初体验</title> <style>/* 选择器 { } */p {/* CSS 属性 */color: red;} </style><p>体验 CSS</p> <link rel="stylesheet" href=…...

Coppelia Sim (v-REP)仿真 机器人3D相机手眼标定与实时视觉追踪 (一)

coppelia sim[V-REP]仿真实现 机器人于3D相机手眼标定与实时视觉追踪 一 标定板的制作生成标定的PDF文件PDF转为图像格式图像加载到仿真中 二 仿真场景设置加载机器人加载的控制dummy ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/b48549d355d8441d8dfc20bc7ba7196…...

CSS常见面试题

&#x1f3af;CSS常见面试题 1.CSS的盒模型2.CSS选择器的优先级3.隐藏元素的方法有哪些&#xff1f;4.px和rem的区别是什么&#xff1f;5.重绘排版有什么区别&#xff1f;6.让一个元素水平垂直居中的方式有哪些&#xff1f;7.CSS的哪些属性可以继承&#xff1f;哪些不可以继承&…...

ChatGPT实现旅游推荐微信小程序

随着旅游行业的快速发展&#xff0c;个性化推荐已成为提升用户体验的重要手段。通过AI技术&#xff0c;提供一个智能旅游推荐小程序&#xff0c;使用户能够轻松获取定制化的旅行建议。 项目概述 项目目标 开发一个AI旅游推荐小程序&#xff0c;基于用户输入的旅行偏好&#…...

基于单片机的智能小区门禁系统设计(论文+源码)

1总体架构 智能小区门禁系统以STM32单片机和WiFi技术为核心&#xff0c;STM32单片机作为主控单元&#xff0c;通过WiFi模块实现与手机APP的连接&#xff0c;构建整个门禁系统。系统硬件包括RFID模块、指纹识别模块、显示屏、按键以及继电器。通过RFID绑定IC卡、APP面部识别、指…...

stm32F103 实现呼吸灯效果

目录 硬件连接 软件实现步骤 初始化系统时钟。 配置 GPIO 引脚。 配置定时器以生成 PWM 信号。 在主循环中调整 PWM 占空比以实现呼吸效果。 示例代码 1. 初始化系统时钟 2. 配置 GPIO 引脚 3. 配置定时器以生成 PWM 信号 4. 在主循环中调整 PWM 占空比以实现呼吸效…...

SAP 为 Copilot Joule 增添协作功能

在最新的SAP TechEd大会上&#xff0c;SAP发布了一系列创新功能&#xff0c;旨在扩展其AI平台Joule的能力&#xff0c;同时推出了其他工具&#xff0c;以提高企业效率并为开发人员提供更多支持。这些创新不仅将推动AI驱动的业务转型&#xff0c;还将加强数据的利用和简化开发流…...

Node.js 模块化

1. 介绍 1.1 什么是模块化与模块 ? 将一个复杂的程序文件依据一定规则&#xff08;规范&#xff09;拆分成多个文件的过程称之为 模块化其中拆分出的 每个文件就是一个模块 &#xff0c;模块的内部数据是私有的&#xff0c;不过模块可以暴露内部数据以便其他模块使用 1.2 什…...

【部署篇】RabbitMq-03集群模式部署

一、准备主机 准备3台主机用于rabbitmq部署&#xff0c;文章中是在centos7上安装部署rabbitmq3.8通过文章中介绍的方式可以同样在centos8、centos9上部署&#xff0c;只需下载对应的版本进行相同的操作。 主机IP角色说明192.168.128.31种子节点192.168.128.32普通节点192.16…...

【硬啃Dash-Fastapi-Admin】03-requirements-pg.txt 速览

文章目录 dash2.18.1 纯Python的Web应用框架Python Dash库的功能介绍和用法示例功能介绍用法示例 Flask-Compress1.15 Flask响应数据的压缩功能介绍用法示例注意事项 feffery-antd-charts0.1.0rc5 数据可视化组件库功能介绍用法示例 feffery-antd-components0.3.8 Dash 第三方组…...

【CS常见问题】你用的是VS2019,最高支持.NET5.0,但是项目将.NET6.0设为目标无法运行,怎么办?

.NET版本问题 报错示例报错分析最简单的方法步骤 报错示例 严重性 代码 说明 项目 文件 行 禁止显示状态 错误 NETSDK1045 当前 .NET SDK 不支持将 .NET 6.0 设置为目标。请将 .NET 5.0 或更低版本设置为目标&#xff0c;或使用支持 .NET 6.0 的 .NET SDK 版本。 ABFview C:\x…...

系统登录接口文档Demo

接口描述 该接口用于用户登录验证。通过用户名和密码进行身份验证&#xff0c;成功后返回一个用于后续请求的认证 token。这个 token 是访问受保护资源的凭证。 时序图&#xff1a; 登录请求&#xff1a; 登录查询接口: POST {url}/api/user/login 请求体: {"username…...

gin入门教程(7): 使用 Logrus + Lumberjack 创建日志中间件

结合 Logrus 和 Lumberjack&#xff0c;可以创建一个高效的日志中间件&#xff0c;用于记录请求和响应。以下是实现步骤&#xff1a; 1. 安装依赖 首先&#xff0c;确保安装了 Logrus 和 Lumberjack&#xff1a; go get github.com/sirupsen/logrus go get gopkg.in/natefin…...

kube-prometheus-stack 自定义 alertmanager 配置推送webhook

创建AlertmanagerConfig资源 在没有使用 prometheus-operator 的情况下&#xff0c;需要手动配置 alertmanager.yaml 来路由&发送从 prometheus 接收的警报。 使用 prometheus-operator 之后&#xff0c;事情变得简单一些。只需要创建 AlertmanagerConfig 资源&#xff0…...

openssl签名报错

在调用RSA_private_encrypt函数时遇到如下报错。 0:error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:309:TypeX509 0:error:2406C06E:random number generator:RAND_DRBG_instantiate:error retrieving entropy:crypto/…...

如何在不使用 VPN 的情况下通过 SOCKS 隧道安全地路由 Web 流量

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 在某些情况下&#xff0c;您可能会发现自己处于一个不安全的网络或者有一个过于严格的防火墙&#xff0c;您会希望确保没有人在监…...

建设企业展示网站/婚恋网站排名前10

iBatis是一个基于SQL映射支持Java和NET的持久层框架&#xff0c;相对Hibernate和ApacheOJB等“一站式”ORM解决方案而言&#xff0c;iBatis 是一种“半自动化”的ORM实现。一、JAR包依赖ibatis-2.3.4.726.jarmysql-connector-java-5.0.8-bin.jar二、SqlMap.propertiesdrivercom…...

自学网站建设基本流程/廊坊seo推广公司

Vlookup函数&#xff0c;可以算是一个数据专员必须要会使用的基本函数了&#xff0c;确实很好用。但是你可能会注意到&#xff0c;Excel一旦数据量过大&#xff0c;打开都费劲了&#xff0c;何况打开后&#xff0c;你还要输入公式计算&#xff0c;就更费劲了&#xff0c;此时你…...

广州白云区疫情/商丘seo外包

在网站中嵌入动画已成为近年来的一个设计趋势&#xff0c;许多公司都已开始转向并拥抱HTML5、CSS3和JavaScript这个技术“三人组”。尽管这些技术还不能制作一些非常复杂的动画&#xff08;像flash所实现的&#xff09;&#xff0c;但是如果拥有好的想法及创造性思维&#xff0…...

司法局网站建设/a5站长网

转自&#xff1a;http://blog.itpub.net/4227/viewspace-536379/ 在10g以前&#xff0c;Oracle的全局索引分区方法只有一种&#xff0c;即范围分区。 SQL> CREATE TABLE T_PART_INDEX (ID NUMBER, NAME VARCHAR2(30), CREATE_DATE DATE); 表已创建。 SQL> INSERT INTO…...

wordpress 4.1 搜索框/天津seo优化

nohup java -jar xxx.jar >xxx.log 2>&1 & ps aux|grep xxx.jar 转载于:https://www.cnblogs.com/lovedaodao/p/7853246.html...

盘锦做网站建设的/晚上偷偷看b站软件推荐

一&#xff1a;安装Sublime Text 3插件的方法安装package control组件&#xff0c;然后直接在线安装&#xff1a;1、按Ctrl调出console&#xff08;注&#xff1a;安装有QQ输入法的这个快捷键会有冲突的。输入法属性设置-输入法管理-取消热键切换至QQ拼音&#xff09; 2、粘贴下…...