• SpringBoot3学习记录(有ssm基础)


    目录

    一、SpringBoot3 介绍

    SpringBoot3 简介

    SpringBoot3 快速入门

    入门总结

    1.为什么依赖不需要写版本

    2.Startrer(启动器)是什么

    3.@SpringBootApplication

    二、SpringBoot3 配置文件

    统一配置管理

    使用yaml配置文件(推荐)

    读取配置文件

    多环境配置和使用

    三、SpringBoot3 整合 SpringMVC

    实现过程

    SpringMvc相关的配置:

    静态资源处理

    自定义拦截器

    四、SpringBoot3 整合 Druid

    操作过程

    五、SpringBoot3 整合 Mybatis

    1.Mybatis整合步骤

    2.mybatis整合实践

    3.声明式事务整合配置

    4.AOP整合配置

    六、SpringBoot3 项目打包和运行


    一、SpringBoot3 介绍

    SpringBoot3 简介

    spring的配置文件或配置类太过繁琐,当编写微服务项目时,每有一个子项目,都需要编写对应的配置文件或配置类等。而SpringBoot能帮我们简单,快速地创建一个独立,生产级别的Spring应用(SpringBoot底层是Spring),大多数SpringBoot应用只需要编写少量配置即可快速整合Spring平台以及第三方技术。

    简单来说,SpringBoot整合了Spring,简化了开发。

    SpringBoot主要目的:

    • 为所有spring开发提供更快捷、可广泛访问的入门体验
    • 设置合理的默认值,也可以根据需求进行适当的调整
    • 提供一系列大型项目通用的非功能性程序(如内置服务器、安全性、指标、运行检查等)
    • 约定大于配置,基本不需要主动编写配置文件或配置类

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

    SpringBoot3 系统要求:

    maven        3.6.3+

    Tomcat        10.0+

    Servlet        9.0+

    JDK             17+

    SpringBoot3 快速入门

    场景:通过浏览器发送 /hello 请求,返回“Hello,SpringBoot 3”

    操作步骤:

    1.创建Maven工程:springboot_mvc

    2.添加依赖 (SpringBoot父工程依赖,web启动器依赖)

    1. <parent>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-parentartifactId>
    4. <version>3.0.5version>
    5. parent>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframework.bootgroupId>
    9. <artifactId>spring-boot-starter-webartifactId>
    10. dependency>
    11. dependencies>

    3.编写启动引导类(SpringBoot项目运行的入口)

    1. @SpringBootApplication
    2. public class Main {
    3. public static void main(String[] args) {
    4. SpringApplication.run(Main.class,args);//自动创建ioc容器,启动tomcat服务器软件
    5. }
    6. }

    4.编程处理类(controller)

    1. @Controller
    2. @RequestMapping("hello")
    3. @ResponseBody
    4. public class HelloController {
    5. @GetMapping
    6. public String hello(){
    7. return "Hello,SpringBoot 3";
    8. }
    9. }

    5.启动项目

    运行Main就行

    入门总结

    1.为什么依赖不需要写版本

            父项目spring-boot-starter-parent的父工程spring-boot-dependencies(版本仲裁中心)中把常见的依赖版本都声明好了。

    2.Startrer(启动器)是什么

            SpringBoot提出了Starter的概念,它是一组预定义的依赖项集合,旨在简化Spring项目的配置和构建过程。Starter包含了一组相关依赖项,以便在启动项目时自动引入需要的库,配置和功能,

    (注意:不仅仅是导入库)。

    像上面项目中导入了spring-boot-starter-web这个启动器,以往要web开发需要导入依赖:spring-webmvc,servlet,json等,还要写对应的配置文件或配置类。但web启动器内部帮我们导入web相关的依赖,还帮我们导入一些相应的web配置。 

    Start启动器有两种:官方提供和第三方提供。

    官方提供的,一般命名为:spring-boot-starter-*

    第三方提供的,一般命名为:*-spring-boot-starter

    官方启动器:Developing with Spring Booticon-default.png?t=N7T8https://docs.spring.io/spring-boot/docs/current/reference/html/using.html?spm=wolai.workspace.0.0.68b623067jPfWP#using.build-systems.starters

    启动器与依赖传递:

    依赖传递是MAVEN底层实现,它并不全面,如:要使用mybatis,需要导入mysql,druid,mybatis。

    启动器是人为根据开发场景设置的,会根据场景包装对应的依赖,如:mybatis的启动器就会包含对应的依赖和配置。

    3.@SpringBootApplication

    @SpringBootApplication添加到启动类上,是一个组合注解,它的子注解有:

    @SpringBootConfiguration

    @EnableAuotConfiguration

    @ComponentScan

    @SpringBootConfiguration:声明当前类是配置类,如果之后想要添加ioc对象可以直接在该类下添加。

    1. @SpringBootApplication
    2. public class Main {
    3. public static void main(String[] args) {
    4. SpringApplication.run(Main.class,args);
    5. }
    6. @Bean
    7. public Object object(){
    8. return new Object();
    9. }
    10. }

    @EnableAutoConfiguration:自动加载配置类,加载我们编写的配置类和SpringBoot内部自带的配置类。

    @ComponentScan:默认扫描当前类所在包以及子包的注解。

    Main方法中的SpringApplication.run(Main.class, args)的功能为:

    1.创建ioc容器,加载配置

    2.启动内置的tomcat服务器

    二、SpringBoot3 配置文件

    统一配置管理

    SpringBoot项目下,进行统一配置管理,如何想设置的参数(端口号,项目根路径,数据库连接信息等等)都集中在一个固定位置命名的配置文件(application.properties、application.yml、application.yaml)中。

    配置文件应该放在SpringBoot工程的src/main/resources目录下。因为此目录是SpringBoot默认的类路径(classpath),配置文件会被自动加载并可供应用程序访问。

    在这个配置文件中使用两种方式设置参数:

    1.固定的key配置参数(官方提供)

    Common Application Propertiesicon-default.png?t=N7T8https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html?spm=wolai.workspace.0.0.68b623067jPfWP#appendix.application-properties

    2.自定义key配置参数(示例application.properties格式)

            如:qiu.name=qiu

            在组件中可以使用@Value(${key})接收参数

    1. #使用SpringBoot提供的key修改程序的参数
    2. server.port=81
    3. #项目访问根路径
    4. server.servlet.context-path=/qiu
    5. #自定义key配置参数
    6. qiu.name=qiu
    7. qiu.age=22
    1. @Controller
    2. @RequestMapping("hello")
    3. @ResponseBody
    4. public class HelloController {
    5. @Value("${qiu.name}")
    6. private String name;
    7. @GetMapping
    8. public String hello(){
    9. System.out.println(name);
    10. return "Hello,SpringBoot 3";
    11. }
    12. }

    使用yaml配置文件(推荐)

    yaml语法:1.数据结构有树状结构呈现,通过缩进表示层级

                       2.连续的项目(集合)通过减号"- "来表示(减号后面有一个空格)

                       3.键值结构key/value使用": "(冒号后面有一个空格)

                       4.yaml配置文件的拓展名为:yml或yaml

    1. server:
    2. port: 82
    3. servlet:
    4. context-path: /qiu
    5. qiu:
    6. user:
    7. name: qiu
    8. age: 22
    9. py:
    10. - a
    11. - b
    12. - c

    读取配置文件

    方式1:@Value("${key}"):该注解本身使用的是di注入,因此使用该注解的类需要放到ioc容器。

    1. @Data
    2. @Component
    3. public class User {
    4. @Value("${qiu.user.name}")
    5. private String name;
    6. @Value("${qiu.user.age}")
    7. private int age;
    8. @Value("${qiu.user.py}")
    9. private List py;
    10. }

    @Value注解key必须写全,而且只能读取单个值。

    方式2:@ConfigurationProperties注解,将注解内prefix指向要赋值的key那一层。

            该注解会把对应的属性赋值(只有类中属性名与指定的那一层key值相同才会赋值)

    1. qiu:
    2. user:
    3. name: qiu2
    4. age: 23
    5. py:
    6. - a
    7. - b
    8. - c
    9. pys:
    10. sex: 1
    1. @Data
    2. @Component
    3. @ConfigurationProperties(prefix = "qiu.user")
    4. public class User {
    5. // @Value("${qiu.user.name}")
    6. private String name;
    7. // @Value("${qiu.user.age}")
    8. private int age;
    9. // @Value("${qiu.user.py}")
    10. private List py;
    11. private String sex;
    12. }

    该测试无误。

    多环境配置和使用

    在开发一个项目过程中会有不同的时期:开发,测试,生产。对应不同的时期所使用的配置参数可能不同(数据库,日志级别等等)。

    这时我们可以在application.yaml(properties)之外再创建 文件名如:application-test.yaml(application-*.yaml)的配置文件,再使用application.yaml中的spring.profiles.active: test来激活application-test.yaml。

    当配置文件内容太多时,也可以使用该方法,如:druid的配置内容可以放在application-druid.yaml。

    如果有多个配置文件需要激活在后面加 " , " 分隔。如:application-test.yaml,application-dev.yaml可以在application.yaml中使用:"spring.profiles.active: test,dev"。

    如果配置文件有重复的key,会按顺序覆盖。

    当项目完成后会被打成一个jar包,我们在执行项目时可以添加命令在启动项目时动态指定要激活哪个配置。

    三、SpringBoot3 整合 SpringMVC

    实现过程

    创建maven项目

    继承父工程:spring-boot-starter-parent

    导入web开发场景的启动器:spring-boot-starter-web

    定义启动类

    1. @SpringBootApplication
    2. public class Main {
    3. public static void main(String[] args) {
    4. SpringApplication.run(Main.class,args);
    5. }
    6. }

    编写controller层

    1. @Controller
    2. @ResponseBody
    3. @RequestMapping("/hello")
    4. public class HelloController {
    5. @GetMapping
    6. public String hello(){
    7. return "你好,springboot";
    8. }
    9. }

    运行启动类即可访问:localhost:8080/hello

    SpringMvc相关的配置:

    server.port        端口号

    server.servlet.context-path        项目访问根路径

    spring.resources.static.locations        静态资源的位置

    spring.http.encoding.charset        Http请求的字符编码

    spring.http.encoding.enabled        响应的字符编码

    静态资源处理

    我们如何访问项目静态资源?

    方式1:将资源放到默认的文件夹

    • classpath:/META-INF/resources/
    • classpath:/resources/(该文件夹与项目自带的resources文件夹不同)
    • classpath:/static/
    • classpath:/public/

    方式2:使用spring.web.resources.static-locations: … 修改

    自定义拦截器

    1.声明拦截器

    1. public class MyInterceptor implements HandlerInterceptor {
    2. @Override
    3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    4. System.out.println("MyInterceptor.preHandle");
    5. return true;
    6. }
    7. }

    2.创建配置类

    1. @Configuration
    2. public class WebConfig implements WebMvcConfigurer {
    3. @Override
    4. public void addInterceptors(InterceptorRegistry registry) {
    5. registry.addInterceptor(new MyInterceptor());
    6. }
    7. }

    只要配置类放在启动类的包或子包下,SpringBoot就会自动扫描。

    四、SpringBoot3 整合 Druid

    整合Druid连接池一般整合两个功能:数据库连接池功能和监控页面。

    但暂时只整合连接池功能,因为druid 1.2.18 目前对springboot3整合并不是很好。

    操作过程

    1.导入依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <parent>
    7. <groupId>org.springframework.bootgroupId>
    8. <artifactId>spring-boot-starter-parentartifactId>
    9. <version>3.0.5version>
    10. parent>
    11. <groupId>com.atguigugroupId>
    12. <artifactId>springboot-starter-druid-04artifactId>
    13. <version>1.0-SNAPSHOTversion>
    14. <properties>
    15. <maven.compiler.source>17maven.compiler.source>
    16. <maven.compiler.target>17maven.compiler.target>
    17. <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starter-webartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframework.bootgroupId>
    26. <artifactId>spring-boot-starter-jdbcartifactId>
    27. dependency>
    28. <dependency>
    29. <groupId>com.alibabagroupId>
    30. <artifactId>druid-spring-boot-3-starterartifactId>
    31. <version>1.2.18version>
    32. dependency>
    33. <dependency>
    34. <groupId>mysqlgroupId>
    35. <artifactId>mysql-connector-javaartifactId>
    36. <version>8.0.28version>
    37. dependency>
    38. <dependency>
    39. <groupId>org.projectlombokgroupId>
    40. <artifactId>lombokartifactId>
    41. <version>1.18.28version>
    42. dependency>
    43. dependencies>
    44. <build>
    45. <plugins>
    46. <plugin>
    47. <groupId>org.springframework.bootgroupId>
    48. <artifactId>spring-boot-maven-pluginartifactId>
    49. plugin>
    50. plugins>
    51. build>
    52. project>

    2.配置文件编写

    1. spring:
    2. datasource:
    3. # 连接池类型
    4. type: com.alibaba.druid.pool.DruidDataSource
    5. # Druid的其他属性配置 springboot3整合情况下,数据库连接信息必须在Druid属性下!
    6. druid:
    7. url: jdbc:mysql://localhost:3306/springboot
    8. username: root
    9. password: 123456
    10. driver-class-name: com.mysql.cj.jdbc.Driver
    11. # 初始化时建立物理连接的个数
    12. initial-size: 5
    13. # 连接池的最小空闲数量
    14. min-idle: 5
    15. # 连接池最大连接数量
    16. max-active: 20
    17. # 获取连接时最大等待时间,单位毫秒
    18. max-wait: 60000
    19. # 申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
    20. test-while-idle: true
    21. # 既作为检测的间隔时间又作为testWhileIdel执行的依据
    22. time-between-eviction-runs-millis: 60000
    23. # 销毁线程时检测当前连接的最后活动时间和当前时间差大于该值时,关闭当前连接(配置连接在池中的最小生存时间)
    24. min-evictable-idle-time-millis: 30000
    25. # 用来检测数据库连接是否有效的sql 必须是一个查询语句(oracle中为 select 1 from dual)
    26. validation-query: select 1
    27. # 申请连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
    28. test-on-borrow: false
    29. # 归还连接时会执行validationQuery检测连接是否有效,开启会降低性能,默认为true
    30. test-on-return: false
    31. # 是否缓存preparedStatement, 也就是PSCache,PSCache对支持游标的数据库性能提升巨大,比如说oracle,在mysql下建议关闭。
    32. pool-prepared-statements: false
    33. # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
    34. max-pool-prepared-statement-per-connection-size: -1
    35. # 合并多个DruidDataSource的监控数据
    36. use-global-data-source-stat: true
    37. logging:
    38. level:
    39. root: debug

    3.创建pojo类和controller层

    1. @Data
    2. public class User {
    3. private Integer id;
    4. private String name;
    5. private Integer age;
    6. private String email;
    7. }
    1. @Controller
    2. @RequestMapping("user")
    3. @ResponseBody
    4. public class UserController {
    5. @Autowired
    6. private JdbcTemplate jdbcTemplate;
    7. @GetMapping
    8. public List show(){
    9. String sql = "select * from user";
    10. List users = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(User.class));
    11. return users;
    12. }
    13. }

    当导入jdbc启动器,springboot会帮我们完成配置类的加载,JdbcTemplate会自动放到ioc容器中,我们需要时注入就行。

    4.编写启动类并启动

    启动项目时会报错,因为springboot3和druid 1.2.18 不兼容,缺少自动装配的配置文件。(druid版本为1.2.20时已兼容,启动时不会报错)

    解决方法:在resources目录下创建

    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

    文件,文件内容为

    com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceAutoConfigure

    五、SpringBoot3 整合 Mybatis

    1.Mybatis整合步骤

    1.1.导入依赖:添加MyBatis和数据库驱动的相关依赖,如使用Mysql数据库,添加MyBatis和MySQL驱动的依赖。

    1.2.配置数据源:在application.yaml中配置数据库连接信息(url,username,password,driver,mybatis的功能配置等)。

    1.3.创建实体类:创建与数据库表对应的实体类。

    1.4.创建Mapper接口:创建与数据库表交互的Mapper接口。

    1.5.创建Mapper接口SQL实现:使用mapper.xml文件或注解方式。

    1.6创建程序启动类

    1.7.注解扫描:在启动类上添加@MapperScan注解,用于扫描和注册Mapper接口。

    1.8.使用Mapper接口

    2.mybatis整合实践

    创建项目:springboot-mybatis

    导入依赖:

    1. <parent>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-parentartifactId>
    4. <version>3.0.5version>
    5. parent>
    6. <dependencies>
    7. <dependency>
    8. <groupId>org.springframework.bootgroupId>
    9. <artifactId>spring-boot-starter-webartifactId>
    10. dependency>
    11. <dependency>
    12. <groupId>org.mybatis.spring.bootgroupId>
    13. <artifactId>mybatis-spring-boot-starterartifactId>
    14. <version>3.0.1version>
    15. dependency>
    16. <dependency>
    17. <groupId>org.springframework.bootgroupId>
    18. <artifactId>spring-boot-starter-jdbcartifactId>
    19. dependency>
    20. <dependency>
    21. <groupId>com.alibabagroupId>
    22. <artifactId>druid-spring-boot-3-starterartifactId>
    23. <version>1.2.18version>
    24. dependency>
    25. <dependency>
    26. <groupId>mysqlgroupId>
    27. <artifactId>mysql-connector-javaartifactId>
    28. <version>8.0.28version>
    29. dependency>
    30. <dependency>
    31. <groupId>org.projectlombokgroupId>
    32. <artifactId>lombokartifactId>
    33. <version>1.18.28version>
    34. dependency>
    35. dependencies>

    配置文件:

    1. server:
    2. port: 80
    3. servlet:
    4. context-path: /
    5. spring:
    6. datasource:
    7. type: com.alibaba.druid.pool.DruidDataSource
    8. druid:
    9. url: jdbc:mysql:///springboot_mybatis
    10. username: root
    11. password: 123456
    12. driver-class-name: com.mysql.cj.jdbc.Driver
    13. mybatis:
    14. configuration: # setting配置
    15. auto-mapping-behavior: full
    16. map-underscore-to-camel-case: true
    17. log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
    18. type-aliases-package: com.qiu.pojo # 配置别名
    19. mapper-locations: classpath:/mapper/*.xml # mapperxml位置

            druid会报错,记得之前的操作。

    创建实体类:

    1. @Data
    2. @ToString
    3. public class User {
    4. private String account ;
    5. private String password ;
    6. private Integer id ;
    7. }

    创建Mapper接口:

    1. public interface UserMapper {
    2. List queryAll();
    3. }

    创建Mapper接口SQL实现:由于application.yaml已经设置了mapperxml的位置,因此只需要在resources下创建mapper.Usermapper.xml

    1. "1.0" encoding="UTF-8" ?>
    2. mapper
    3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    4. "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
    5. <mapper namespace="com.qiu.mapper.UserMapper">
    6. <select id="queryAll" resultType="user">
    7. select * from user
    8. select>
    9. mapper>

    创建启动类:

    1. @SpringBootApplication
    2. @MapperScan("com.qiu.mapper")//mapper接口所在的位置
    3. public class Main {
    4. public static void main(String[] args) {
    5. // System.out.println("Hello world!");
    6. SpringApplication.run(Main.class,args);
    7. }
    8. }

    注解扫描:

    在启动类上添加@MapperScan,以前想要mapper接口和mapperxml对应上我们需要为两个文件创建统一的文件路径,但springboot可以在application.json中指定mapperxml的路径,在启动类上@MapperScan上指定mapper接口的路径,这样就不需要两个文件的统一路径。

    controller操作:

    1. @Controller
    2. @ResponseBody
    3. @RequestMapping("user")
    4. public class UserController {
    5. @Autowired
    6. private UserMapper userMapper;
    7. @GetMapping
    8. public List getUsers(){
    9. return userMapper.queryAll();
    10. }
    11. }

    访问localhost:80/user

    3.声明式事务整合配置

    导入依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-jdbcartifactId>
    4. dependency>

    SpringBoot项目会自动配置一个 DataSourceTransactionManager,所以我们只需在方法(或者类)加上 @Transactional 注解,就自动纳入 Spring 的事务管理了

    1. @Transactional
    2. public void addUser(){
    3. User user = new User();
    4. user.setId(4);
    5. user.setAccount("user4");
    6. user.setPassword("pass4");
    7. userMapper.addUser(user);
    8. }

    4.AOP整合配置

    导入依赖

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-aopartifactId>
    4. dependency>

    直接使用注解即可:com.qiu.advice.LogAdvice

    1. @Component
    2. @Aspect
    3. @Order(4)
    4. public class LogAdvice {
    5. @Before("execution(* com..service.*.*(..))")
    6. public void before(JoinPoint joinPoint){
    7. String classname = joinPoint.getClass().getSimpleName();
    8. String methodname = joinPoint.getSignature().getName();
    9. System.out.println("methodname = " + methodname+" classname = " + classname);
    10. }
    11. }

    六、SpringBoot3 项目打包和运行

    在普通的web工程中,要打包需要打成war包,然后再tomcat服务器中运行。

    在springboot工程中,由于内置了tomcat,所以可以直接打成jar包,使用命令执行java -jar xx。

    1.添加打包插件:不使用插件也可以把项目打成jar包,但运行时会找不到项目入口,所以需要使用springboot的打包插件

    1. <build>
    2. <plugins>
    3. <plugin>
    4. <groupId>org.springframework.bootgroupId>
    5. <artifactId>spring-boot-maven-pluginartifactId>
    6. plugin>
    7. plugins>
    8. build>

    2.打包

    3.命令启动和命令参数

    命令参数:

            命令格式:java -jar  [选项] [参数]

    1. -D=:设置系统属性,可以通过`System.getProperty()`方法在应用程序中获取该属性值。例如:java -jar -Dserver.port=8080 myapp.jar。
    2. -X:设置JVM参数,例如内存大小、垃圾回收策略等。常用的选项包括:
               -Xmx:设置JVM的最大堆内存大小,例如 -Xmx512m 表示设置最大堆内存为512MB。
               -Xms:设置JVM的初始堆内存大小,例如 `-Xms256m` 表示设置初始堆内存为256MB。
    3. -Dspring.profiles.active=:指定Spring Boot的激活配置文件,可以通过application-.properties或 application-.yml文件来加载相应的配置。例如:java -jar -Dspring.profiles.active=dev myapp.jar。

    命令示例:java -jar -Dserver.port=81 springboot-mybatis-1.0-SNAPSHOT.jar

                      java -jar -Dserver.port=81 -Dspring.profiles.active=test,dev springboot-mybatis-1.0-SNAPSHOT.jar

  • 相关阅读:
    Servlet
    SpringSecurity6从入门到上天系列第七篇:讲明白SpringBoot的自动装配完善上篇文章中的结论
    在 React Native 中实现 3D 动画
    界面控件DevExpress WinForm v22.2——即将拥有新的HTML & CSS模板
    不可以涩涩!AI续写软件初体验;迁移学习路线图;谷歌新闻非官方搜索API;CS295『因果推理』2021课程资料;前沿论文 | ShowMeAI资讯日报
    安装淘宝镜像cnpm报错
    自学SLAM(6)相机与图像实践:OpenCV处理图像与图像拼接(点云)
    【Hack The Box】windows练习-- ServMon
    SAP OData 开发教程 - 从入门到提高(包含 SEGW, RAP 和 CDP)
    同事都说有SQL注入风险,我非说没有
  • 原文地址:https://blog.csdn.net/abcd661054026/article/details/136598449