【SpringBoot3】--01.快速入门、基本框架原理、常用注解、yaml配置文件、日志配置

news2024/11/15 17:36:29

文章目录

  • SpringBoot3核心特性
    • 1.简介
      • 1. 1前置知识
      • 1.2 环境要求
      • 1.3SpringBoot是什么
    • 2.快速入门
      • 2.1开发流程
        • 2.1.1创建项目
        • 2.1.2导入场景
        • 2.1.3 主程序
        • 2.1.4 业务
        • 2.1.5 测试
        • 2.1.6 打包
      • 2.2 特性小结
        • 2.2.1 简化整合
        • 2.2.2简化开发
        • 2.2.3 简化配置
        • 2.2.4 简化部署
        • 2.2.5 简化运维
      • 2.3 Spring Initializr创建向导
    • 3.应用分析
      • 3.1依赖管理机制
      • 3.2自动配置机制
        • 3.2.1 初步理解
        • 3.2.2完整流程
      • 3.3如何学好SpringBoot
    • 4.核心功能
      • 4.1 常用注解
        • 4.1.1 组件注册
        • 4.1.2 条件注解
        • 4.1.3属性绑定
        • 4.1.4@Scope
        • 4.1.5@ImportResource和@Import
        • 4.1.6@ComponentScan
        • 4.1.7 @Lazy
        • 4.1.8 @Value
        • 4.1.9@PropertySource
      • 4.2YAML配置文件
        • 4.2.1基本语法
        • 4.2.2示例
        • 4.2.3 细节
        • 4.2.4 小技巧:lombok
      • 4.3日志配置
        • 4.3.1简介
        • 4.3.2日志格式
        • 4.3.3记录日志
        • 4.3.4日志级别
        • 4.3.5日志分组
        • 4.3.6文件输出
        • 4.3.7文件归档与滚动切割
        • 4.3.8自定义配置
        • 4.3.9切换日志组合
        • 4.3.10 最佳实战

SpringBoot3核心特性

学习视频:尚硅谷SpringBoot3视频

1.简介

1. 1前置知识

  • Java17
  • Spring、SpringMVC、MyBatis
  • Maven、IDEA

1.2 环境要求

环境&工具版本(or later)
SpringBoot3.0.5+
IDEA2021.2.1+
Java17+
Maven3.5+
Tomcat10.0+
Servlet5.0+
GraalVM Community22.3+
Native Build Tools0.9.19+

1.3SpringBoot是什么

SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring)

大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术

特性:

  • 快速创建独立 Spring 应用

    • SSM:导包、写配置、启动运行
  • 直接嵌入Tomcat、Jetty or Undertow(无需部署 war 包)【Servlet容器】

    • linux java tomcat mysql: war 放到 tomcat 的 webapps下
    • jar: java环境; java -jar
  • 重点:提供可选的starter,简化应用整合

    • 场景启动器(starter):web、json、邮件、oss(对象存储)、异步、定时任务、缓存…
    • 导包一堆,控制好版本。
    • 为每一种场景准备了一个依赖; web-starter。mybatis-starter
  • **重点:**按需自动配置 Spring 以及 第三方库

    • 如果这些场景我要使用(生效)。这个场景的所有配置都会自动配置好。
    • 约定大于配置:每个场景都有很多默认配置。
    • 自定义:配置文件中修改几项就可以
  • 提供生产级特性:如 监控指标、健康检查、外部化配置等

    • 监控指标、健康检查(k8s)、外部化配置
  • 无代码生成、无xml

总结:简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。

2.快速入门

场景:浏览器发送**/hello**请求,返回"Hello,Spring Boot 3!"

2.1开发流程

2.1.1创建项目

maven项目

<!--    所有springboot项目都必须继承自 spring-boot-starter-parent -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.5</version>
    </parent>

2.1.2导入场景

场景启动器

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

2.1.3 主程序

@SpringBootApplication //这是一个SpringBoot应用
public class MainApplication {

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

2.1.4 业务

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){

        return "Hello,Spring Boot 3!";
    }

}

2.1.5 测试

默认启动访问: localhost:8080

2.1.6 打包

<!--    SpringBoot应用打包插件-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

mvn clean package把项目打成可执行的jar包

java -jar demo.jar启动项目

2.2 特性小结

2.2.1 简化整合

导入相关的场景,拥有相关的功能。场景启动器

默认支持的所有场景:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

  • 官方提供的场景:命名为:spring-boot-starter-*
  • 第三方提供场景:命名为:*-spring-boot-starter

场景一导入,万物皆就绪

2.2.2简化开发

无需编写任何配置,直接开发业务

2.2.3 简化配置

application.properties

  • 集中式管理配置。只需要修改这个文件就行 。
  • 配置基本都有默认值
  • 能写的所有配置都在: https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#appendix.application-properties

2.2.4 简化部署

打包为可执行的jar包。

linux服务器上有java环境。

2.2.5 简化运维

修改配置(外部放一个application.properties文件)、监控、健康检查。

2.3 Spring Initializr创建向导

image-20230709095605683

选择场景:

image-20230709095704849

创建好整个项目结构

image-20230709095927785

3.应用分析

3.1依赖管理机制

思考:

1、为什么导入starter-web所有相关依赖都导入进来?

  • 开发什么场景,导入什么场景启动器。
  • maven依赖传递原则。A-B-C: A就拥有B和C
  • 导入 场景启动器。 场景启动器 自动把这个场景的所有核心依赖全部导入进来

2、为什么版本号都不用写?

  • 每个boot项目都有一个父项目spring-boot-starter-parent
  • parent的父项目是spring-boot-dependencies
  • 父项目 版本仲裁中心,把所有常见的jar的依赖版本都声明好了。
  • 比如:mysql-connector-j

3、自定义版本号

  • 利用maven的就近原则

    • 直接在当前项目properties标签中声明父项目用的版本属性的key

      image-20230709101422636

    • 直接在导入依赖的时候声明版本

      image-20230709101445988

4、第三方的jar包

  • boot父项目没有管理的需要自行声明好
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>

image.png

3.2自动配置机制

3.2.1 初步理解

  • 自动配置的 Tomcat、SpringMVC 等

    • 导入场景,容器中就会自动配置好这个场景的核心组件。
    • 以前:DispatcherServlet、ViewResolver、CharacterEncodingFilter…
    • 现在:自动配置好的这些组件
    • 验证:容器中有了什么组件,就具有什么功能
    public static void main(String[] args) {

        //java10: 局部变量类型的自动推断
        var ioc = SpringApplication.run(MainApplication.class, args);

        //1、获取容器中所有组件的名字
        String[] names = ioc.getBeanDefinitionNames();
        //2、挨个遍历:
        // dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartResolver
        // SpringBoot把以前配置的核心组件现在都给我们自动配置好了。
        for (String name : names) {
            System.out.println(name);
        }

    }
  • 默认的包扫描规则

    • @SpringBootApplication 标注的类就是主程序类
    • SpringBoot只会扫描主程序所在的包及其下面的子包,自动的component-scan功能
    • 自定义扫描路径
      • @SpringBootApplication(scanBasePackages = “com.atguigu”)
      • @ComponentScan("com.atguigu") 直接指定扫描的路径
  • 配置默认值

    • 配置文件的所有配置项是和某个类的对象值进行一一绑定的。
    • 绑定了配置文件中每一项值的类: 属性类
    • 比如:
      • ServerProperties绑定了所有Tomcat服务器有关的配置
      • MultipartProperties绑定了所有文件上传相关的配置
      • 参照官方文档:或者参照 绑定的 属性类
  • 按需加载自动配置

    • 导入场景spring-boot-starter-web
    • 场景启动器除了会导入相关功能依赖,导入一个spring-boot-starter,是所有starterstarter,基础核心starter
    • spring-boot-starter导入了一个包 spring-boot-autoconfigure。包里面都是各种场景的AutoConfiguration自动配置类
    • 虽然全场景的自动配置都在 spring-boot-autoconfigure这个包,但是不是全都开启的。
      • 导入哪个场景就开启哪个自动配置

总结: 导入场景启动器、触发 spring-boot-autoconfigure这个包的自动配置生效、容器中就会具有相关场景的功能

3.2.2完整流程

思考:
1、SpringBoot怎么实现导一个starter、写一些简单配置,应用就能跑起来,我们无需关心整合
2、为什么Tomcat的端口号可以配置在application.properties中,并且Tomcat能启动成功?
3、导入场景后哪些自动配置能生效

image-20230709112200819

自动配置流程细节梳理:

**1、**导入starter-web:导入了web开发场景

  • 1.场景启动器导入了相关场景的所有依赖:starter-jsonstarter-tomcatspringmvc
  • 2.每个场景启动器都引入了一个spring-boot-starter核心场景启动器
  • 3.核心场景启动器引入了spring-boot-autoconfigure包。
  • 4.spring-boot-autoconfigure里面囊括了所有场景的所有配置。
  • 5.只要这个包下的所有类都能生效,那么相当于SpringBoot官方写好的整合功能就生效了。
  • 6.SpringBoot默认却扫描不到 spring-boot-autoconfigure下写好的所有配置类。(这些配置类给我们做了整合操作),默认只扫描主程序所在的包

2、主程序@SpringBootApplication

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {---------}
  • 1、@SpringBootApplication由三个注解组成@SpringBootConfiguration@EnableAutoConfiguratio@ComponentScan
  • 2、SpringBoot默认只能扫描自己主程序所在的包及其下面的子包,扫描不到 spring-boot-autoconfigure包中官方写好的配置类
  • 3、@EnableAutoConfiguration:SpringBoot 开启自动配置的核心

image-20230709112933669

这个注解可以@Import导入下面的类,这个类的作用其实是批量导入组件,@import将指定的类或配置文件导入到当前类中,可以用于导入其他类的定义、配置文件等,但不会将其加入到IOC容器中。这个类内部的方法还获取了一些注册信息,其实调试发现就是主程序所在的包的路径,故帮助我们扫描主程序所在的包和子包路径下所有组件

image-20230709113835419

    • 1.是由@Import(AutoConfigurationImportSelector.class)提供功能:利用getAutoConfigurationEntry(annotationMetadata)批量给容器中导入组件。

      调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类

      利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

      META-INF/spring.factories位置来加载一个文件。

      默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
      spring-boot-autoconfigure-x.x.x.RELEASE.jar包里面也有META-INF/spring.factories 最新版本springboot其实换了文件路径——>来自于spring-boot-autoconfigure META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

    • 2.SpringBoot启动会默认加载 142个配置类。上面的主程序自带的注解会排除一些

    • 3.这142个配置类来自于spring-boot-autoconfigureMETA-INF/spring/**org.springframework.boot.autoconfigure.AutoConfiguration.imports**文件指定的

      image-20230709114256508

    • 项目启动的时候利用 @Import 批量导入组件机制把 autoconfigure 包下的142 xxxxAutoConfiguration类导入进来(自动配置类

    • 虽然导入了142个自动配置类

  • 4、按需生效:

    • 并不是这142个自动配置类都能生效
    • 每一个自动配置类,都有条件注解@ConditionalOnxxx,只有条件成立,才能生效

3、xxxxAutoConfiguration自动配置类

  • 1、给容器中使用@Bean 放一堆组件。
  • 2、每个自动配置类都可能有这个注解@EnableConfigurationProperties(**ServerProperties**.class),用来把配置文件中配的指定前缀的属性值封装到 xxxProperties属性类
  • 3、以Tomcat为例:把服务器的所有配置都是以server开头的。配置都封装到了属性类中。
  • 4、给容器中放的所有组件的一些核心参数,都来自于**xxxPropertiesxxxProperties都是和配置文件绑定(这些类都通过@EnableConfigurationProperties(xxxx)注解把前缀修饰**
  • 只需要改配置文件的值,核心组件的底层参数都能修改

**4、**写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)

核心流程总结:

1.导入starter,就会导入autoconfigure包。

2.autoconfigure 包里面 有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定的所有启动要加载的自动配置类

3.@EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来。xxxAutoConfiguration 是有条件注解进行按需加载

4.xxxAutoConfiguration给容器中导入一堆组件,组件都是从 xxxProperties中提取属性值

5.xxxProperties又是和配置文件进行了绑定

**效果:**导入starter、修改配置文件,就能修改底层行为。

3.3如何学好SpringBoot

框架的框架、底层基于Spring。能调整每一个场景的底层行为。100%项目一定会用到底层自定义

摄影:

  • 傻瓜:自动配置好。
  • 单反:焦距、光圈、快门、感光度…
  • 傻瓜+单反

1.理解自动配置原理

    1. 导入starter –> 生效xxxxAutoConfiguration --> 组件 –> xxxProperties --> 配置文件

2.理解其他框架底层

    1. 如Mybatis的拦截器,和Springboot框架无关,不懂别的框架底层就不可能写好

3.可以随时定制化任何组件

    1. 配置文件
    2. 自定义组件

普通开发:导入starter,Controller、Service、Mapper、偶尔修改配置文件

高级开发:自定义组件、自定义配置、自定义starter

核心:

  • 这个场景自动配置导入了哪些组件,我们能不能Autowired进来使用
  • 能不能通过修改配置改变组件的一些默认参数
  • 需不需要自己完全定义这个组件
  • 场景定制化

最佳实战

  • 选场景,导入到项目

    • 官方:starter
    • 第三方:去仓库搜
  • 写配置,改配置文件关键项

    • 数据库参数(连接地址、账号密码…)
  • 分析这个场景给我们导入了哪些能用的组件

    • 自动装配这些组件进行后续使用
    • 不满意boot提供的自动配好的默认组件
      • 定制化
        • 改配置
        • 自定义组件

整合redis:

  • 选场景:spring-boot-starter-data-redis

    • 场景AutoConfiguration 就是这个场景的自动配置类
  • 写配置:

    • 分析到这个场景的自动配置类开启了哪些属性绑定关系
    • @EnableConfigurationProperties(RedisProperties.class)
    • 修改redis相关的配置
  • 分析组件:

    • 分析到 RedisAutoConfiguration 给容器中放了 StringRedisTemplate
    • 给业务代码中自动装配 StringRedisTemplate
  • 定制化

    • 修改配置文件
    • 自定义组件,自己给容器中放一个 StringRedisTemplate

4.核心功能

4.1 常用注解

SpringBoot摒弃XML配置方式,改为全注解驱动

4.1.1 组件注册

@Configuration@SpringBootConfiguration

@Bean@Scope

@Controller、 @Service、@Repository、@Component

@Import

@ComponentScan

以前的步骤:通过spring配置文件,如果纯xml配置,需要写Bean对象,唯一标识id,全类名,然后通过set注入或者其他注入方式注入默认属性值

现在的步骤:

1、@Configuration 编写一个配置类(配置类其实也会被存入IOC容器,可以通过ctrl + 左键点击这个注解发现内嵌了@Component注解)。其实也可以使用上面的@SpringBootConfiguration注解,本质其实一样,所以Spring相关的核心配置使用SpringBoot的,而通用配置使用默认的

image-20230709105521930

2、在配置类中,自定义方法给容器中注册组件。配合@Bean,如果是第三方的我们直接根据类型,写入为配置类的方法,返回它的类型,然后直接return new出来的对象

image-20230709105530489

2.1、@Configuration注解spring 5.2以后多了属性 proxyBeanMethods,可以设置为true或者false,默认为true(效果代表:是不是代理Bean的方法),如果为true说明为代理对象调用方法,我们在获取这个对象的时候,会从容器检查有没有这个类的对象,有就拿,没有就创建 (保持组件单实例)。主要用于解决组件依赖问题。当不更改这个值,组件在配置类配置依赖可以直接通过set方法然后传入配置类的其他组件的注入方法(即带有@Bean的方法)。我们不想有这种依赖关系,设置成false就是轻量级模式。测试设置为false对于单个Bean从容器获取多次还是单实例的,但依赖的情况下,Bean内部其他的Bean就不是ioc容器的那个了,而是一个新new的。

3、或使用@Import 导入第三方的组件(可以写在组件类(@Conponent,@Controller等)或者配置类上面,与配置类的注解放在一起),在括号中写对应类的 .class字节码文件(默认value值,不用写属性,且是一个数组(可以一次导入多个组件到容器))。或者我们可以使用全类名(推荐:其实不管怎么样默认ioc容器注入的组件的id名称仍是全类名。因为我们开发过程中可能会修改依赖,而如果导入IOC的时候如果删掉之前一些现在用不到的依赖,这种情况下,本身靠字符串的全类名不会引起报错,但是使用字节码文件的时候不存在这个类会大面积报错),对应name属性
image-20230709105626454

4.1.2 条件注解

如果注解指定的条件成立,则触发指定行为

@ConditionalOnXxx

@ConditionalOnClass:如果类路径中存在这个类,则触发指定行为

@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为

@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为

@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为

场景:

  • 如果存在FastsqlException这个类,给容器中放一个Cat组件,名cat01,
  • 否则,就给容器中放一个Dog组件,名dog01
  • 如果系统中有dog01这个组件,就给容器中放一个 User组件,名zhangsan
  • 否则,就放一个User,名叫lisi

注意:

  • 放在类级别,如果注解判断生效,则整个配置类才生效
  • 放在方法级别,单独对这个方法进行注解判断

@ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值

@ConditionalOnRepositoryType (org.springframework.boot.autoconfigure.data)
@ConditionalOnDefaultWebSecurity (org.springframework.boot.autoconfigure.security)
@ConditionalOnSingleCandidate (org.springframework.boot.autoconfigure.condition)
@ConditionalOnWebApplication (org.springframework.boot.autoconfigure.condition)
@ConditionalOnWarDeployment (org.springframework.boot.autoconfigure.condition)
@ConditionalOnJndi (org.springframework.boot.autoconfigure.condition)
@ConditionalOnResource (org.springframework.boot.autoconfigure.condition)
@ConditionalOnExpression (org.springframework.boot.autoconfigure.condition)
@ConditionalOnClass (org.springframework.boot.autoconfigure.condition)
@ConditionalOnEnabledResourceChain (org.springframework.boot.autoconfigure.web)
@ConditionalOnMissingClass (org.springframework.boot.autoconfigure.condition)
@ConditionalOnNotWebApplication (org.springframework.boot.autoconfigure.condition)
@ConditionalOnProperty (org.springframework.boot.autoconfigure.condition)
@ConditionalOnCloudPlatform (org.springframework.boot.autoconfigure.condition)
@ConditionalOnBean (org.springframework.boot.autoconfigure.condition)
@ConditionalOnMissingBean (org.springframework.boot.autoconfigure.condition)
@ConditionalOnMissingFilterBean (org.springframework.boot.autoconfigure.web.servlet)
@Profile (org.springframework.context.annotation)
@ConditionalOnInitializedRestarter (org.springframework.boot.devtools.restart)
@ConditionalOnGraphQlSchema (org.springframework.boot.autoconfigure.graphql)
@ConditionalOnJava (org.springframework.boot.autoconfigure.condition)

4.1.3属性绑定

方法① :@ConfigurationProperties: 声明组件的属性和配置文件哪些前缀开始项进行绑定,可以写在组件Bean上,也可以写到配置类中的配置Bean的方法上

  • 将容器中任意组件(Bean)的属性值和配置文件的配置项的值进行绑定

    • 1、给容器中注册组件

      • ①在配置类外使用@ConfigurationProperties结合@Component,配置类内无需写任何方法

        image-20230709111008648

      • ②配置类内使用@Bean结合@ConfigurationProperties,配置类外不用写任何注解

        image-20230709111157353

    • 2、使用@ConfigurationProperties 声明组件和配置文件的哪些配置项进行绑定

方法② : @EnableConfigurationProperties:快速注册注解(这是写于配置类上的注解,使用@Import注解导入的Bean不会进行属性绑定)

  • 场景:SpringBoot默认只扫描自己主程序所在的包。如果导入第三方包,即使组件上标注了 @Component、@ConfigurationProperties 注解,也没用。因为组件都扫描不进来,此时使用这个注解就可以快速进行属性绑定并把组件注册进容器

image-20230709111552391

image-20230709111626922

4.1.4@Scope

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
    
   @AliasFor("scopeName")
   String value() default "";
 
   @AliasFor("value")
   String scopeName() default "";
   
   ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}

scopeName
scopeName是为了声明Bean的作用域,在Spring4.2版本以前,有singleton, prototype两种模式,4.2之后新加了web作用域(request, session, globalsession)。

singleton单例模式,顾名思义即Spring IOC容器对于一个Bean,只会有一个共享的Bean实例。这一个单一的实例会被存储到单例缓存(singleton cache)中,当有请求或者是引用时,IOC容器都会返回存储在singleton cache的同一个实例。

prototype多实例模式,即当每次客户端向容器获取Bean的时候,IOC容器都会新建一个实例并返回。与单例不同的是,在IOC容器启动的时候并不会创建Bean的实例,并且在有请求创建Bean实例之后也不会管理该实例的生命周期,而是由客户端自行处理。

request:web应用针对每一次HTTP请求都会创建一个新的Bean实例,且该实例仅在该次HTTP请求有效。

session:针对每一个session会创建一个Bean实例,且生命周期为该session有效期间。
globalsession:仅基于portlet的web应用才有意义,否则可以当作session使用。
这五种scopeName的使用方法 (也可以直接写对应的字符串,无视大小写)

@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(scopeName = WebApplicationContext.SCOPE_REQUEST)
@Scope(scopeName = WebApplicationContext.SCOPE_SESSION)
@Scope(scopeName = "globalSession")

ScopeProxyMode
proxyMode表明了@Scope注解的Bean是否需要代理。

  • DEFAULT:proxyMode的默认值,一般情况下等同于NO,即不需要动态代理。
  • NO:不需要动态代理,即返回的是Bean的实例对象。
  • INTERFACES:代理的对象是一个接口,即@Scope的作用对象是接口,这种情况是基于jdk实现的动态代理。
  • TARGET_CLASS:代理的对象是一个类,即@Scope的作用对象是一个类,是以生成目标类扩展的方式创建代理,基于CGLib实现动态代理
@Scope(proxyMode = ScopedProxyMode.DEFAULT)
@Scope(proxyMode = ScopedProxyMode.NO)
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)

4.1.5@ImportResource和@Import

如果想把别的xml文件的配置也导入,不想重新手写配置类和注解,可以直接在配置类或者组件类上写@ImportResource("classpath:/xxxxxx.xml")可以把xml的配置文件的组件导入IOC容器

@Import注解提供了三种用法

  1. @Import一个普通类 spring会将该类加载到spring容器中,需要有无参构造器
  2. @Import一个类,该类实现了ImportBeanDefinitionRegistrar接口,在重写的registerBeanDefinitions方法里面,能拿到BeanDefinitionRegistry bd的注册器,能手工往beanDefinitionMap中注册 beanDefinition,这种方式注册既能进行复杂的判断,也能对Bean进行生命周期和名字更改等功能
  3. @Import一个类 该类实现了ImportSelector 重写selectImports方法该方法返回了String[]数组的对象,数组里面的类都会注入到spring容器当中

4.1.6@ComponentScan

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
    @AliasFor("basePackages")
    String[] value() default {};

    @AliasFor("value")
    String[] basePackages() default {};

    Class<?>[] basePackageClasses() default {};

    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;

    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

    String resourcePattern() default "**/*.class";

    boolean useDefaultFilters() default true;

    Filter[] includeFilters() default {};

    Filter[] excludeFilters() default {};

    boolean lazyInit() default false;

    @Retention(RetentionPolicy.RUNTIME)
    @Target({})
    public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;

        @AliasFor("classes")
        Class<?>[] value() default {};

        @AliasFor("value")
        Class<?>[] classes() default {};

        String[] pattern() default {};
    }
}

1. value

首先它的value值对应要扫描的包名,可以是一个数组,放入要扫描的包名。

2. excludeFilters = {@Filter(type=FilterType.xxxx, classes={xxx,xxx,xxx}) …}

可以填入一个数组,类型为@Filter注解数组,可以排除要扫描的包。可以按注解,或者是类的类型,或者是正则排除【几乎不用】,或者是AspectJ语法【几乎不用】,

type=FilterType.ASSUGNABLE_TYPE按类型排除

如我们不扫描@Controller注解的类和@Service注解的类
这里我测试发现排除这个注解,并不会把衍生的@RestController注解的组件排除注册

@ComponentScan(excludeFilters = {
        @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {ComponentScan.class,Service.class})
})

3. includeFilters

需要进行设置属性关闭默认扫描规则useDefaultFilters = false
用法和上面没有什么区别

4. 自定义类型扫描

定义一个类,实现TypeFilter接口,实现它的方法
第一个参数metadataReader:可以通过它获取正在扫描的类的信息:如注解,类的信息,类的资源信息。

进一步比如类名,可以用如className.contains("xxx")的方法去判断是否名字包含字符【其实本质不如用上面的正则】

第二个参数metadataReaderFactory可以获得其他的容器组件的信息
使用的时候,只需要@Filter(type=FilterType.CUSTOM,classes={MyFilter})指定使用我们的过滤规则

public class MyFilter implements TypeFilter {
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        return false;
    }
}

4.1.7 @Lazy

可以给配置类中加载的Bean上加,即便是单实例Bean,也可以实现懒加载,ioc创建不加载,第一次获取才加载

4.1.8 @Value

使用这个注解标注在我们的Bean类的字段属性上,可以进行赋值。

  1. 基本数值
  2. 可以写spEL:#{}【很少用】
  3. 可以写${}:取出配置文件中的值【在运行环境变量中的值】

4.1.9@PropertySource

使用这个注解在配置类上可以读取外部配置文件读取到环境变量中。
@PropertySource用于指定外部属性文件的位置,可以将属性文件中的属性值注入到Spring Bean中。它通常与@Value注解一起使用,将属性文件中的值注入到单个属性中。
@ConfigurationProperties用于将属性文件中的值绑定到一个Java对象上。它可以将属性文件中的多个属性值注入到一个Java对象中。与@Value注解不同,@ConfigurationProperties可以将属性文件中的值注入到多个属性中。

4.2YAML配置文件

痛点:SpringBoot 集中化管理配置,application.properties

问题:配置多以后难阅读和修改,层级结构辨识度不高

YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(是另一种标记语言)。

  • 设计目标,就是方便人类读写
  • 层次分明,更适合做配置文件
  • 使用.yaml.yml作为文件后缀

4.2.1基本语法

  • 大小写敏感
  • 使用缩进表示层级关系,k: v,使用空格分割k,v
  • 缩进时不允许使用Tab键,只允许使用空格。换行
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • # 表示注释,从这个字符一直到行尾,都会被解析器忽略。

支持的写法:

  • 对象键值对的集合,如:映射(map)/ 哈希(hash) / 字典(dictionary)
  • 数组:一组按次序排列的值,如:序列(sequence) / 列表(list)
  • 纯量:单个的、不可再分的值,如:字符串、数字、bool、日期

4.2.2示例

@Component
@ConfigurationProperties(prefix = "person") //和配置文件person前缀的所有配置进行绑定
@Data //自动生成JavaBean属性的getter/setter
//@NoArgsConstructor //自动生成无参构造器
//@AllArgsConstructor //自动生成全参构造器
public class Person {
    private String name;
    private Integer age;
    private Date birthDay;
    private Boolean like;
    private Child child; //嵌套对象
    private List<Dog> dogs; //数组(里面是对象)
    private Map<String,Cat> cats; //表示Map
}

@Data
public class Dog {
    private String name;
    private Integer age;
}

@Data
public class Child {
    private String name;
    private Integer age;
    private Date birthDay;
    private List<String> text; //数组
}

@Data
public class Cat {
    private String name;
    private Integer age;
}

properties表示法

person.name=张三
person.age=18
person.birthDay=2010/10/12 12:12:12
person.like=true
person.child.name=李四
person.child.age=12
person.child.birthDay=2018/10/12
person.child.text[0]=abc
person.child.text[1]=def
person.dogs[0].name=小黑
person.dogs[0].age=3
person.dogs[1].name=小白
person.dogs[1].age=2
person.cats.c1.name=小蓝
person.cats.c1.age=3
person.cats.c2.name=小灰
person.cats.c2.age=2

yaml表示法

person:
  name: 张三
  age: 18
  birthDay: 2010/10/10 12:12:12
  like: true
  child:
    name: 李四
    age: 20
    birthDay: 2018/10/10
    text: ["abc","def"]
  dogs:
    - name: 小黑
      age: 3
    - name: 小白
      age: 2
  cats:
    c1:
      name: 小蓝
      age: 3
    c2: {name: 小绿,age: 2} #对象也可用{}表示

4.2.3 细节

  • birthDay 推荐写为 birth-day

  • 文本

    • 单引号不会转义【\n 则为普通字符串显示】
    • 双引号会转义【\n会显示为换行符
  • 大文本

    • |开头,大文本写在下层,保留文本格式换行符正确显示
    • >开头,大文本写在下层,折叠换行符变为空格
  • 多文档合并

    • 使用---可以把多个yaml文档合并在一个文档中,每个文档区依然认为内容独立

4.2.4 小技巧:lombok

简化JavaBean 开发。自动生成构造器、getter/setter、自动生成Builder模式等

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>compile</scope>
</dependency>

使用@Data等注解

4.3日志配置

规范:项目开发不要编写System.out.println(),应该用日志记录信息

日志门面日志实现 (没有对应关系)
JCL(Jakarta Commons Logging)Log4j
SLF4j(Simple Logging Facade for Java)JUL(java.util.logging)
jboss-loggingLog4j2
Logback

4.3.1简介

  1. Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。

    1. spring5及以后 commons-logging被spring直接自己写了。
  2. 支持 jul,log4j2,logback。SpringBoot 提供了默认的控制台输出配置,也可以配置输出为文件。

  3. logback是默认使用的。

  4. 虽然日志框架很多,但是我们不用担心,使用 SpringBoot 的默认配置就能工作的很好

SpringBoot怎么把日志默认配置好的

1、每个starter场景,都会导入一个核心场景spring-boot-starter

2、核心场景引入了日志的所用功能spring-boot-starter-logging

3、默认使用了logback + slf4j 组合作为默认底层日志

4、日志是系统一启动就要用xxxAutoConfiguration是系统启动好了以后放好的组件,后来用的。

5、日志是利用监听器机制配置好的。ApplicationListener

6、日志所有的配置都可以通过修改配置文件实现。以logging开始的所有配置。

4.3.2日志格式

2023-03-31T13:56:17.511+08:00  INFO 4944 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-03-31T13:56:17.511+08:00  INFO 4944 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.7]

默认输出格式:

  • 时间和日期:毫秒级精度
  • 日志级别:ERROR, WARN, INFO, DEBUG, or TRACE.
  • 进程 ID
  • —: 消息分割符
  • 线程名: 使用[]包含
  • Logger 名: 通常是产生日志的类名
  • 消息: 日志记录的内容

注意: logback 没有FATAL级别,对应的是ERROR

默认值:参照:spring-bootadditional-spring-configuration-metadata.json文件

默认输出格式值:%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}

可修改为:'%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} ===> %msg%n'

-5 代表左对齐五个字符
%logger 代表当前类
%n 换行

4.3.3记录日志

Logger logger = LoggerFactory.getLogger(getClass());

或者使用Lombok的@Slf4j注解

4.3.4日志级别

  • 由低到高:ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF

    • 只会打印指定级别及以上级别的日志
    • ALL:打印所有日志
    • TRACE:追踪框架详细流程日志,一般不使用
    • DEBUG:开发调试细节日志
    • INFO:关键、感兴趣信息日志
    • WARN:警告但不是错误的信息日志,比如:版本过时
    • ERROR:业务错误日志,比如出现各种异常
    • FATAL:致命错误日志,比如jvm系统崩溃
    • OFF:关闭所有日志记录
  • 不指定级别的所有类,都使用root指定的级别作为默认级别

  • SpringBoot日志默认级别是 INFO

  1. application.properties/yaml中配置logging.level.<logger-name>=<level>指定日志级别

    image-20230709142933203

  2. level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF,定义在 LogLevel类中

  3. root 的logger-name叫root,可以配置logging.level.root=warn,代表所有未指定日志级别都使用 root 的 warn 级别

4.3.5日志分组

比较有用的技巧是:

将相关的logger分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设置

logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging.level.tomcat=trace

SpringBoot 预定义两个组

NameLoggers
weborg.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sqlorg.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

4.3.6文件输出

SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在application.properties中添加logging.file.name or logging.file.path配置项。

logging.file.namelogging.file.path示例效果
未指定未指定仅控制台输出
指定未指定my.log写入指定文件。可以加路径
未指定指定/var/log写入指定目录,文件名为spring.log
指定指定以logging.file.name为准

4.3.7文件归档与滚动切割

归档:每天的日志单独存到一个文档中。

切割:每个文件10MB,超过大小切割成另外一个文件。

  1. 每天的日志应该独立分割出来存档。如果使用logback(SpringBoot 默认整合),可以通过application.properties/yaml文件指定日志滚动规则。
  2. 如果是其他日志系统,需要自行配置(添加log4j2.xml或log4j2-spring.xml)
  3. 支持的滚动规则设置如下
配置项描述
logging.logback.rollingpolicy.file-name-pattern日志存档的文件名格式(默认值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)
logging.logback.rollingpolicy.clean-history-on-start应用启动时是否清除以前存档(默认值:false)
logging.logback.rollingpolicy.max-file-size存档前,每个日志文件的最大大小(默认值:10MB)
logging.logback.rollingpolicy.total-size-cap日志文件被删除之前,可以容纳的最大大小(默认值:0B)。设置1GB则磁盘存储超过 1GB 日志后就会删除旧日志文件
logging.logback.rollingpolicy.max-history日志文件保存的最大天数(默认值:7).

4.3.8自定义配置

通常我们配置 application.properties 就够了。当然也可以自定义。比如:

日志系统自定义
Logbacklogback-spring.xml, logback-spring.groovy, logback.xml, or logback.groovy
Log4j2log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging)logging.properties

如果可能,我们建议您在日志配置中使用-spring 变量(例如,logback-spring.xml 而不是 logback.xml)。如果您使用标准配置文件,spring 无法完全控制日志初始化。

最佳实战:自己要写配置,配置文件名加上 xx-spring.xml

4.3.9切换日志组合

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

log4j2支持yaml和json格式的配置文件

格式依赖文件名
YAMLcom.fasterxml.jackson.core:jackson-databind + com.fasterxml.jackson.dataformat:jackson-dataformat-yamllog4j2.yaml + log4j2.yml
JSONcom.fasterxml.jackson.core:jackson-databindlog4j2.json + log4j2.jsn

4.3.10 最佳实战

  1. 导入任何第三方框架,先排除它的日志包,因为Boot底层控制好了日志
  2. 修改 application.properties 配置文件,就可以调整日志的所有行为。如果不够,可以编写日志框架自己的配置文件放在类路径下就行,比如logback-spring.xmllog4j2-spring.xml
  3. 如需对接专业日志系统,也只需要把 logback 记录的日志灌到 kafka之类的中间件,这和SpringBoot没关系,都是日志框架自己的配置,修改配置文件即可
  4. 业务中使用slf4j-api记录日志。不要再 sout 了

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

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

相关文章

iOS通用链接(UniversalLink)配置详细流程

一、Universal Links 配置过程 登录苹果账号后&#xff0c;点击创建的APP 的Bundle ID&#xff0c;跳转到APP 信息页面。记录下Team ID 和Bundle ID 备用。勾选上 功能列表上的 ”Associated Domains“选项。 配置苹果后台 创建一个text空文本文件&#xff0c;去掉文件后缀&a…

【Linux | Shell】构建基础脚本 - 读书笔记

目录 一、创建第一个Shell脚本1.1 执行多个命令1.2 创建 shell 脚本1.2.1 指定使用的shell1.2.2 在脚本文件各行输入命令1.2.3 添加执行权限1.2.4 执行脚本 1.3 显示消息——echo命令 二、使用变量2.1 三四五 一、创建第一个Shell脚本 前面得文章介绍过一些基础的 Linux 命令了…

【InnoDB 存储引擎】5.4.5 The Slow Query Log(慢日志实验, 详细描述了与 MySQL 相关的慢日志方方面面)

文章目录 1 慢日志实验环境准备2 开始实验2.1 实验 1&#xff1a;超过查询时间相关慢日志并观察2.2 实验 2&#xff1a;不使用索引相关慢日志并观察2.3 实验 3&#xff1a;打印额外的慢日志信息2.4 实验 4&#xff1a;使用 mysqldumpslow 工具分析日志文件2.5 实验 5&#xff1…

【雕爷学编程】Arduino动手做(153)---2.4寸TFT液晶触摸屏模块5

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【计算机组成与体系结构Ⅰ】实验5 CPU组成与机器指令执行实验

一、实验目的 1&#xff1a;将微程序控制器同执行部件&#xff08;整个数据通路&#xff09;联机&#xff0c;组成一台模型计算机。 2&#xff1a;用微程序控制器控制模型机数据通路。 3&#xff1a;通过CPU运行几条机器指令&#xff08;排除中断指令&#xff09;组成的简单…

MARLIN: Masked Autoencoder for facial video Representation LearnINg

题目MARLIN: Masked Autoencoder for facial video Representation LearnINg译题MARLIN&#xff1a;用于面部视频表示的 maked 自动编码器 LearnINg时间2023年期刊/会议CVPR 论文链接&#xff1a;MARLIN_MASKED_Autoencoder_for_Facial_Video_Representation_Learning MARLIN…

C++11右值引用(移动构造、完美转发等)

在讲解移动构造和完美转发之前&#xff0c;我们需要先了解什么是右值引用。 但在讲解右值引用之前&#xff0c;我们也得知道左值和右值分别是什么&#xff0c;有什么区别。 目录 左值与右值 左值与左值引用 右值与右值引用 引用和右值引用的区别 移动构造 移动赋值 插…

基于simulink处理监控视频以选择包含运动的帧(附源码)

一、前言 此示例演示如何处理监控视频以选择包含运动的帧。安全问题要求使用摄像机对重要位置进行持续监控。为了有效地记录、查看和存档这些海量数据&#xff0c;您可以减小视频帧大小或减少录制的视频帧总数。此示例说明了后一种方法。在其中&#xff0c;相机视野中的运动会…

1762_gcc编译c语言makefile自动生成工具的Perl实现

全部学习汇总&#xff1a; GreyZhang/g_makefile: Learn makefile from all kinds of tutorials on the web. Happy hacking and lets find an common way so we may dont need to touch makefile code any more! (github.com) 前阵子实现了一个CodeWarrior嵌入式开发环境的自动…

【Java从入门到大牛】数组详解

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Java从入门到大牛 &#x1f320; 首发时间&#xff1a;2023年7月9日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43e…

Python + pymysql 之 MySQL 查询操作

在MySQL中构建一个测试表&#xff0c;如下&#xff1a; 查询单条数据 # -*- coding: UTF-8 -*- import pymysqldef mysql_query():"""MySQL查询:return:"""# 打开数据库连接db pymysql.connect(host"127.0.0.1",user"root"…

IDEA 配置 openjdk,jre

使用 idea 配置 zip 版本的 openjdk 和 jre&#xff0c;我使用的时 redhat 提供的 jdk 和 jre。 一、下载 idea、jdk 和 jre 红帽下载地址为&#xff1a; jdk 和 jre 安装地址根据个人配置&#xff0c;我的配置如下&#xff1a; 下划线的分别为我的 jdk 和 jre 保存路径 二…

简单学习UE5.2的PCG框架插件里的基础概念

目标 最近了解到5.2版本推出了实验性的功能PCG框架&#xff0c;以及用它做的范例 Electric Dreams。 本篇我简单学习它的一些基础概念&#xff0c;做一些记录。 0. 启用插件 此功能相关的类型都在PCG插件中&#xff0c;因此首先要确保启用了PCG插件&#xff1a; 1. PCGGr…

为什么进程地址空间中包括操作系统?

今天聊聊进程地址空间这点小事。 说到进程的地址空间&#xff0c;大家可能都知道这样一张图&#xff1a; 这张图就是Linux程序运行起来后所谓的进程地址空间&#xff0c;这里包括我们熟悉的代码区、数据区、以及堆区和栈区&#xff0c;今天我们不讲解这些区域&#xff0c;而是…

Vue生态及实践 - SSR(上)

目录 目标 理论 Rendering 你真的需要SSR亦或是同构吗&#xff1f; 同构实践 通用代码 同构第一步&#xff1a;避免单例 src/app.js src/store.js src/router.js 同构第二步&#xff1a;Server entry【服务端进入】&#xff1b;Client entry【客户端进入】 src/entry…

ESP32设备驱动-AS5600磁性旋转位置传感器

AS5600磁性旋转位置传感器 文章目录 AS5600磁性旋转位置传感器1、AS5600介绍2、硬件准备3、软件准备4、驱动实现1、AS5600介绍 AS5600 是一款可编程的 12 位高分辨率非接触式磁性旋转位置传感器。 AS5600可以作为磁性电位器或磁性编码器使用,具有出色的可靠性和耐用性。 与传…

网页版代码编辑器实现

接着前几天写的博客https://blog.csdn.net/woyebuzhidao321/article/details/131495855&#xff0c;提到了涉及vscode网页版工作区创建的api&#xff0c;这两天一时兴起&#xff0c;搞了一个网页版的代码编辑器&#xff0c;如果在2020年10月之前&#xff0c;实现一个网页版代码…

活动笔记 | 「企业人效提升路径」之数字化实践

6月27日&#xff0c;由人力资源智享会联合盖雅工场等机构主办的2023中国人力资源数字化论坛在北京顺利举办。盖雅工场高级解决方案顾问谷天毅先生发表了主题为 《企业人效提升路径之数字化实践》 的分享。 以下是分享内容&#xff0c;enjoy~ △ 盖雅工场高级解决方案顾问谷天…

httpx 返回都是乱码问题,非编码问题。

因为python 的requests 不能使用抓http2 的报文。所以看了一些httpx的使用。但是发现httpx 不能自动解压&#xff0c;text打印出来的都是乱码。一开始以为是编码格式的bug &#xff0c;但是使用chardet 确认了确实是utf-8.然后怀疑是压缩的问题。先去官网搜了一些文档 文档说会…

opencv4.7.0编译opencv-contrib-4.7.0以及CUDA

0、引言 最近工作中需要用到使用CUDA加速后的opencv进行传统算法的开发&#xff0c;在编程之前&#xff0c;需要先解决环境编译和lib库问题&#xff0c;本文就是记录自己编译opencv-4.7.0的全过程。 1、CUDA下载和安装 可参考我之前的博客WIN10安装配置TensorRT详解中的前几…