SpringBoot


微服务阶段

JavaSE:OOP

MySQL:持久化

HTML+css+js+jQuery+框架:视图

JavaWeb:独立开发MVC三层架构的网站

SSM:框架:简化开发流程,配置变复杂

Spring再简化:SpringBoot——>微服务架构

服务越来越多:SpringCloud

SpringBoot

核心:自动装配

约定大于配置

什么是微服务

一种架构风格

好处:

  1. 节省了调用资源
  2. 每个功能元素的服务都是可替换的、可独立升级的软件代码

第一个Spring程序

官方:提供了一个快速生成的网站。IDEA集成了

  • 可以在官网直接下载后,导入idea开发
  • 直接用idea创建一个SpringBoot项目

原理初探

自动配置

pom.xml

  • spring-boot-dependencies:核心依赖,在父工程中
  • 我们在写或引入一些SpringBoot依赖的时候,不需要指定版本,因为有这些版本仓库

启动器

  • SpringBoot的启动场景
  • 比如spring-boot-starter-web,会帮我们自动导入web环境所有的依赖
  • SpringBoot会将所有的功能场景,都变成一个个的启动器
  • 我们要使用什么功能,只要找到对应的启动器就可以了

主程序

1
2
3
4
5
6
7
8
@SpringBootApplication
public class HelloWorldApplication {

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

}
  • 注解

    • ```java
      @SpringBootConfiguration//springboot的配置
      @Configuration//spring配置类
          @Component//spring的组件
      
      @EnableAutoConfiguration//自动配置
      @AutoConfigurationPackage//自动配置包
          @Import(AutoConfigurationPackages.Registrar.class)//导入选择器
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17

      * META-INF/spring.factories:自动配置的核心文件

      * 结论:SpringBoot所有的自动配置都在启动类中被扫描并加载`spring.factories`。所有的自动配置类都在这里面,但不一定生效,要判断条件是否成立。只要导入了对应的start,就有了对应的启动器,我们自动装配就会生效,配置成功。

      1. SpringBoot启动的时候,从类路径下/META-INF/spring.factories获取指定的值
      2. 将这些自动配置的类导入容器,自动配置就会生效,帮我们进行自动配置
      3. 以前我们需要自动配置的东西,SpringBoot帮我们做了
      4. 整个Java,解决方案和自动配置的东西都在spring-boot-autoconfigure-2.5.4.jar这个包下
      5. 它会将所有需要导入的组件以类名的方式返回,这些组件就会被添加到容器
      6. 容器中也会存在非常多的xxxxAutoConfiguration的文件,就是这些类给容器中导入了这个场景需要的所有组件,并自动配置
      7. 有了自动配置类,免去了手动配置

      * ```java
      public static void main(String[] args) {
      SpringApplication.run(HelloWorldApplication.class, args);
      }

    执行main方法,开启了一个服务

    • SpringApplication做了四件事情
      1. 推断应用的类型是普通的项目还是web项目
      2. 查找并加载所有可用初始化器,设置到initializers属性中
      3. 查找出所有的应用程序监听器,设置到listeners属性中
      4. 推断并设置main方法的定义类,找到运行的主类

关于SpringBoot,谈谈理解

  • 自动装配
  • run方法

YAML

可以注入到配置类中

可以直接给实体类赋值

1
2
3
4
5
6
7
8
9
10
person:
name: cat
age: 13
happy: true
birth: 2025/05/19
maps: {12: 45}
lists: [456, 321]
dog:
name: dog
age: 14
1
2
3
4
5
6
7
8
9
public class Person {
private String name;
private int age;
private boolean happy;
private Date birth;
private Map<String, Object> maps;
private List<Object> lists;
private Dog dog;
}

JSR303校验

自动装配的原理

  1. SpringBoot启动会加载大量的自动配置类
  2. 我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类中
  3. 再看这个自动配置类到底配置了哪些组件
  4. 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只要在配置文件中指定这些属性的值即可
    • xxxxAutoConfiguration:自动配置类,给容器增加组件
    • xxxxProperties:封装配置文件中相关属性

SpringBoot Web开发

SpringBoot帮我们配置了什么?我们能不能进行修改?能修改哪些东西?能不能扩展?

  • xxxxAutoConfiguration 向容器中自动配置组件
  • xxxxProperties 自动配置类,装配配置文件中自定义的一些内容

要解决的问题

  • 导入静态资源
  • 首页
  • 模板引擎
  • 装配扩展SpringMVC
  • 增删改查
  • 拦截器
  • 国际化

静态资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
registration.addResourceLocations(resource);
}
});
}

总结:

  1. 在SpringBoot中,我们可以使用以下方式处理静态资源
    • webjars localhost:8080\webjars
    • public,static,/**,resources localhost:8080\
  2. 优先级:resources>static>public

首页如何定制

模板引擎

结论:只要需要使用Thymeleaf,只需要导入对应的依赖就可以了。我们将HTML页面放在templates目录下

扩展装配SpringMVC

如果想diy一些定制化的功能,只要写这个组件,然后将它交给SpringBoot,SpringBoot就会帮我们自动装配

在SpringBoot中,有非常多的configuration,会帮助我们进行拓展配置。只要看到这个,我们就要注意了

SpringData

DruidDataSource

MyBatis

SpringSecurity

Shiro

Swagger

学习目标:

  • 了解Swagger的作用和概念
  • 巩固前后端分离
  • 在SpringBoot中继承Swagger

简介

前后端分离

Vue+SpringBoot

后端时代:前端只用管理静态页面

前后端分离时代:

  • 后端:后端控制层,服务层,数据访问层
  • 前端:前端控制层,视图层
    • 伪造后端数据,json。不需要后端,前端依旧能跑起来
  • 前后端如何交互? API
  • 前后端相对独立,松耦合
  • 前后端甚至可以部署在不同服务器上

产生一个问题:

  • 前后端集成联调,前后端人员无法做到及时协商,尽早解决

解决方案:

  • 制定一个schema,实时更新最新API,降低集成风险
  • 早些年:制定Word文档
  • 前后端分离:
    • 前端测试后端接口:postman
    • 后端提供接口,需要实时更新最新的消息及改动

Swagger

  • 号称世界上最流行的API框架
  • RestFul API文档在线自动生成工具->API文档与API定义同步更新
  • 直接运行,可以在线测试API接口
  • 支持多种语言

在项目中使用Swagger

  • 需要使用jar包
    • swagger2
    • ui

SpringBoot集成Swagger

基础Swagger配置

1
2
3
4
5
@Configuration
@EnableSwagger2
public class SwaggerConfig {

}

测试运行:http://localhost:8080/swagger-ui.html

配置Swagger

Swagger的bean实例Docket

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());
}

private ApiInfo apiInfo() {

Contact contact = new Contact("Dogegg", "www.baidu.com", "2222222222");

return new ApiInfo(
"Api Documentation",
"Api Documentation",
"v1.0",
"urn:tos",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}

Swagger配置扫描接口

1
2
3
4
5
6
7
8
9
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.dogegg.controller"))
.paths(PathSelectors.ant("/dogegg"))
.build();
}

配置是否启动Swagger

1
2
3
4
5
6
7
8
9
10
@Bean
public Docket docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(false)
.select()
.apis(RequestHandlerSelectors.basePackage("com.dogegg.controller"))
// .paths(PathSelectors.ant("/dogegg"))
.build();
}

我只希望我的Swagger在生产环境中使用,在发布的时候不使用?

  • 判断是不是生产环境
  • 注入enable
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Configuration
@EnableSwagger2
public class SwaggerConfig {

@Bean
public Docket docket(Environment environment) {

Profiles profiles = Profiles.of("dev");
boolean b = environment.acceptsProfiles(profiles);

return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.enable(b)
.select()
.apis(RequestHandlerSelectors.basePackage("com.dogegg.controller"))
// .paths(PathSelectors.ant("/dogegg"))
.build();
}

private ApiInfo apiInfo() {

Contact contact = new Contact("Dogegg", "www.baidu.com", "2222222222");

return new ApiInfo(
"Api Documentation",
"Api Documentation",
"v1.0",
"urn:tos",
contact,
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList());
}

}

分组和接口注释

配置分组:.groupName("")

如何配置多个分组:多个Docket

总结:

  1. 可以通过Swagger给一些比较难理解的属性或接口,增加注释信息
  2. 接口文档实时更新
  3. 可以在线测试

任务

异步任务

在方法和application中都加上@Async注解

定时任务

核心接口

1
2
3
4
5
TaskScheduler
TaskExecutor
@EnableScheduling
@Scheduled
Cron表达式

邮件发送

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
1
2
3
4
5
6
7
8
void contextLoads() {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("验证码");
mailMessage.setText(String.valueOf(Math.random()));
mailMessage.setTo("2452499907@qq.com");
mailMessage.setFrom("2452499907@qq.com");
mailSender.send(mailMessage);
}
1
2
3
4
5
spring.mail.username=2452499907@qq.com
spring.mail.password=antaqsueycymecbg
spring.mail.host=smtp.qq.com

spring.mail.properties.mail.smtp.ssl.enable=true

SpringBoot整合

SpringBoot操作数据:spring-data jpa jdbc MongoDB redis

SpringData也是与SpringBoot齐名的项目

说明:在SpringBoot2.x之后,原来使用的jedis被替换为了lettuce

jedis:直连,操作是不安全的,如果要避免,就要使用jedis pool 更像BIO模式

lettuce:才用netty,实例可以在多个线程中进行共享,不存在线程不安全 更像NIO模式

分布式Dubbo+Zookeeper+SpringBoot

分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统

RPC

https://www.jianshu.com/p/2accc2840a1b

Dubbo


文章作者: ZDogEgg
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 ZDogEgg !