快速开始

方式一、官网下载

使用在线地址:https://start.spring.io/,配置Spring Boot项目,配置完成后下载到本地使用idea导入项目。

方式二、使用idea快速生成

image.png

项目结构

image.png
image.png

SpringBoot 常用设置

修改端口号

image.png

自定义banner

image.png

原理初探

自动装配原理

pom.xml

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

启动器

  1. <!-- 启动器 -->
  2. <!-- web依赖:tomcat, dispatcherServlet.xml -->
  3. <dependency>
  4. <groupId>org.springframework.boot</groupId>
  5. <artifactId>spring-boot-starter-web</artifactId>
  6. </dependency>
  7. <!-- 所有的SpringBoot依赖都是使用这个开头的:spring-boot-starter -->
  • 启动器:说白了就是SpringBoot的启动场景
  • 比如spring-boot-starter-web,它就会帮我们自动导入web环境所有的依赖
  • SpringBoot会将所有的功能场景,都变成一个个的启动器
  • 我们要使用什么功能,就只需要找到对应的启动器就可以了

SpringBoot官方启动器地址:
https://docs.spring.io/spring-boot/docs/2.5.3/reference/html/using.html#using.build-systems.starters

主程序

  1. import org.springframework.boot.SpringApplication;
  2. import org.springframework.boot.autoconfigure.SpringBootApplication;
  3. // SpringBoot程序的主入口
  4. // @SpringBootApplication:标注这个类是一个SpringBoot的应用
  5. @SpringBootApplication
  6. public class HelloworldApplication {
  7. public static void main(String[] args) {
  8. // 将SpringBoot应用启动
  9. SpringApplication.run(HelloworldApplication.class, args);
  10. }
  11. }

@SpringBootApplication

@SpringBootConfiguration:SpringBoot的配置
  • @Configuration:Spring配置类
  • @Component:说明也是一个spring的组件

@EnableAutoConfiguration:自动配置
  • @AutoConfigurationPackage:自动配置包
    • @Import(AutoConfigurationPackages.Registrar.class):自动配置包注册
  • @Import(AutoConfigurationImportSelector.class):自动配置导入选择

整合JDBC

整合Mybatis

整合Redis

SpringBoot操作数据:spring-data,例如:jpa、jdbc、mongodb、redis
说明:在SpringBoot2.x之后,原来使用的jedis被替换了lettuce

  • jedis:采用直接,多个线程操作的话,是不安全的,如果想避免可使用jedis pool连接池。 更像BIO模式。
  • lettuc:采用netty异步调用,实例可以在多个线程中进行共享,不存在线程不安全的情况,可以减少线程数量。更像Nio模式。

    原理解析

    image.png
    SpringBoot所有配置类,都有一个自动配置类,redis的为:RedisAutoConfiguration
    自动配置类都会绑定一个properties配置文件,redis的为:RedisProperties

    RedisProperties配置

    1. public class RedisProperties {
    2. /**
    3. * Database index used by the connection factory.
    4. */
    5. private int database = 0;
    6. /**
    7. * Connection URL. Overrides host, port, and password. User is ignored. Example:
    8. * redis://user:password@example.com:6379
    9. */
    10. private String url;
    11. /**
    12. * Redis server host.
    13. */
    14. private String host = "localhost";
    15. /**
    16. * Login username of the redis server.
    17. */
    18. private String username;
    19. /**
    20. * Login password of the redis server.
    21. */
    22. private String password;
    23. /**
    24. * Redis server port.
    25. */
    26. private int port = 6379;
    27. /**
    28. * Whether to enable SSL support.
    29. */
    30. private boolean ssl;
    31. /**
    32. * Read timeout.
    33. */
    34. private Duration timeout;
    35. /**
    36. * Connection timeout.
    37. */
    38. private Duration connectTimeout;
    39. /**
    40. * Client name to be set on connections with CLIENT SETNAME.
    41. */
    42. private String clientName;
    43. /**
    44. * Type of client to use. By default, auto-detected according to the classpath.
    45. */
    46. private ClientType clientType;
    47. ...
    48. }

    RedisAutoConfiguration

    ```java @Configuration(proxyBeanMethods = false) @ConditionalOnClass(RedisOperations.class) @EnableConfigurationProperties(RedisProperties.class) @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class }) public class RedisAutoConfiguration {

    @Bean @ConditionalOnMissingBean(name = “redisTemplate”) // 我们可以自定义redisTemplate来替换这个默认的模板 @ConditionalOnSingleCandidate(RedisConnectionFactory.class) public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {

    1. /*
    2. 默认的RedisTemplate没有过多的设置,redis对象都是需要序列化
    3. 两个泛型都是<Object,Object>的类型,我们后面使用需要强制转换<String Object>
    4. */
    5. RedisTemplate<Object, Object> template = new RedisTemplate<>();
    6. template.setConnectionFactory(redisConnectionFactory);
    7. return template;

    }

  1. // 由于String是redis中最常用的类型,所以单独提出来一个bean
  2. @Bean
  3. @ConditionalOnMissingBean
  4. @ConditionalOnSingleCandidate(RedisConnectionFactory.class)
  5. public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
  6. StringRedisTemplate template = new StringRedisTemplate();
  7. template.setConnectionFactory(redisConnectionFactory);
  8. return template;
  9. }

}

  1. <a name="vp9Kw"></a>
  2. ### 整合测试
  3. <a name="szun4"></a>
  4. #### 导入依赖
  5. ```xml
  6. <!-- pom.xml -->
  7. <dependency>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-data-redis</artifactId>
  10. </dependency>

配置连接

  1. # application.yml
  2. spring:
  3. # 配置redis
  4. redis:
  5. host: localhost
  6. port: 6379
  7. lettuce:
  8. pool:
  9. max-active: 8

测试

  1. @SpringBootTest
  2. class SpringbootRedisApplicationTests {
  3. @Autowired
  4. private RedisTemplate redisTemplate;
  5. @Test
  6. void contextLoads() {
  7. /*
  8. redisTemplate 操作不同的数据类型
  9. opsForValue 操作字符串 类似String
  10. opsForList 操作List 类似List
  11. opsForSet
  12. opsForHash
  13. opsForZSet
  14. opsForGeo
  15. opsForHyperLogLog
  16. 除了基本的操作,常用的方法都可以直接通过redisTemplate操作,例如事务、基本的CRUD等
  17. */
  18. // 获取redis的连接对象,一般很少用
  19. // RedisConnection connection = redisTemplate.getConnectionFactory().getConnection();
  20. // connection.flushDb();
  21. // connection.flushAll();
  22. redisTemplate.opsForValue().set("myKey", "harry中文名字");
  23. System.out.println(redisTemplate.opsForValue().get("myKey"));
  24. }
  25. }

通过 redis-cli 连接测试使用 redis 服务

  1. docker exec -it redis-test /bin/bash
  2. redis-cli

image.png

自定义RedisTemplate

  1. package com.kuang.config;
  2. import com.fasterxml.jackson.annotation.JsonAutoDetect;
  3. import com.fasterxml.jackson.annotation.PropertyAccessor;
  4. import com.fasterxml.jackson.databind.ObjectMapper;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. import org.springframework.data.redis.connection.RedisConnectionFactory;
  8. import org.springframework.data.redis.core.RedisTemplate;
  9. import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
  10. import org.springframework.data.redis.serializer.StringRedisSerializer;
  11. @Configuration
  12. public class RedisConfig {
  13. // 自定义 redisTemplate
  14. @Bean
  15. public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
  16. RedisTemplate<String, Object> template = new RedisTemplate<>();
  17. template.setConnectionFactory(redisConnectionFactory);
  18. // Json序列化配置
  19. Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
  20. ObjectMapper om = new ObjectMapper();
  21. om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
  22. om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
  23. jackson2JsonRedisSerializer.setObjectMapper(om);
  24. // String的序列化
  25. StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
  26. // key采用String的序列化方式
  27. template.setKeySerializer(stringRedisSerializer);
  28. // hash的key也采用String的序列化方式
  29. template.setHashKeySerializer(stringRedisSerializer);
  30. // value序列化方式采用jackson
  31. template.setValueSerializer(jackson2JsonRedisSerializer);
  32. // hash的value序列化方式采用jackson
  33. template.setHashValueSerializer(jackson2JsonRedisSerializer);
  34. template.afterPropertiesSet();
  35. return template;
  36. }
  37. }

SpringSecurity(安全)

在web开发中,安全第一位!过滤器,拦截器~
功能性需求:否
做网站:安全应该在什么时候考虑?设计之初!

shiro、SpringSecurity
认证、授权

权限

  • 功能权限
  • 访问权限
  • 菜单权限
  • … 拦截器,过滤器:大量的原生代码~ 冗余

任务

异步任务

  1. package com.kuang.controller;
  2. import com.kuang.service.AsyncService;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class AsyncController {
  8. @Autowired
  9. AsyncService asyncService;
  10. @RequestMapping("/hello")
  11. public String hello() {
  12. asyncService.hello();
  13. return "ok";
  14. }
  15. }
  1. package com.kuang.service;
  2. import org.springframework.scheduling.annotation.Async;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class AsyncService {
  6. // 告诉Spring这是一个异步的方法
  7. @Async
  8. public void hello() {
  9. try {
  10. Thread.sleep(3000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. System.out.println("数据正在处理...");
  15. }
  16. }

定时任务

  1. package com.kuang.service;
  2. import org.springframework.scheduling.annotation.Scheduled;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class ScheduleService {
  6. // cron 表达式
  7. // 秒 分 时 日 月 周几
  8. @Scheduled(cron = "0 * * * * 0-7")
  9. public void hello() {
  10. System.out.println("hello, 被执行了~");
  11. }
  12. }

邮件发送(邮件任务)

  1. spring:
  2. mail:
  3. username: 732150595@qq.com
  4. password: ******
  5. host: smtp.qq.com
  6. properties:
  7. mail:
  8. smtp:
  9. ssl:
  10. enable: true # 开启加密验证,qq邮箱特有
  1. package com.kuang;
  2. import org.junit.jupiter.api.Test;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. import org.springframework.mail.SimpleMailMessage;
  6. import org.springframework.mail.javamail.JavaMailSender;
  7. import org.springframework.mail.javamail.JavaMailSenderImpl;
  8. import org.springframework.mail.javamail.MimeMessageHelper;
  9. import javax.mail.MessagingException;
  10. import javax.mail.internet.MimeMessage;
  11. import java.io.File;
  12. @SpringBootTest
  13. class Springboot05MybatisApplicationTests {
  14. @Autowired
  15. JavaMailSenderImpl mailSender;
  16. @Test
  17. void testSimpleMail() {
  18. // 一个简单的邮件
  19. SimpleMailMessage mailMessage = new SimpleMailMessage();
  20. mailMessage.setSubject("你好啊!我是SpringBoot发的邮件!");
  21. mailMessage.setText("我正在学习SpringBoot,要一起吗?");
  22. mailMessage.setFrom("732150595@qq.com");
  23. mailMessage.setTo("huangxubo23@gmail.com");
  24. mailSender.send(mailMessage);
  25. }
  26. @Test
  27. void testMimeMail() throws MessagingException {
  28. // 一个复杂的邮件
  29. MimeMessage mimeMessage = mailSender.createMimeMessage();
  30. // 组装
  31. MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
  32. helper.setSubject("你好啊!我是SpringBoot发的复杂邮件");
  33. helper.setText("<h2 style='color:red'>我正在学习SpringBoot,要一起吗?</h2>", true);
  34. // 附件
  35. helper.addAttachment("OG-Spring.png", new File("/Users/harryhuang/Downloads/OG-Spring.png"));
  36. helper.setFrom("732150595@qq.com");
  37. helper.setTo("huangxubo23@gmail.com");
  38. mailSender.send(mimeMessage);
  39. }
  40. /**
  41. * 邮件发送发放封装
  42. * @param html
  43. * @param subject
  44. * @param text
  45. * @throws MessagingException
  46. */
  47. public void sendMail(Boolean html, String subject, String text) throws MessagingException {
  48. // 一个复杂的邮件
  49. MimeMessage mimeMessage = mailSender.createMimeMessage();
  50. // 组装
  51. MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, html);
  52. helper.setSubject(subject);
  53. helper.setText(text, html);
  54. // 附件
  55. helper.addAttachment("OG-Spring.png", new File("/Users/harryhuang/Downloads/OG-Spring.png"));
  56. helper.setFrom("732150595@qq.com");
  57. helper.setTo("huangxubo23@gmail.com");
  58. mailSender.send(mimeMessage);
  59. }
  60. }

集成Swagger

  • 了解Swagger的作用和概念
  • 了解前后端分离
  • 在SpringBoot中集成Swagger

背景介绍

前后端分离
后端时代:前端只用管理静态页面;模板引擎 JSP =》后端是主力
前后端分离时代:

  • 后端:后端控制层、服务层、数据访问层
  • 前端:前端控制层、视图层
  • 前后端相对独立,松耦合
  • 前后端可以部署在不同的服务器上

产生一个问题:

  • 前后端集成联调,前端人员和后端人员无法做到“及时协商,尽早解决”,最终导致问题集中爆发

解决方案:

  • 首先指定schema(计划的提纲),实时更新最新API,降低集成的风险
  • 早些年:制定word计划文档
  • 前后端分离:
    • 前端测试后端接口:postman
    • 后端提供接口,需要实时更新最新的消息及改动

Swagger简介

  • 号称世界上最流行的Api框架
  • ResetFul Api文档在线自动生成工具=》Api文档与API定义同步更新
  • 直接运行,可以在线测试API接口
  • 支持多种语言:Java、PHP…

在项目使用Swagger需要springbox

  • swagger2
  • swagger-ui

SpringBoot集成Swagger

  1. 新建一个SpringBoot web项目
  2. 导入Swagger相关依赖 ```xml io.springfox springfox-swagger2 2.10.5

io.springfox springfox-swagger-ui 2.10.5

  1. 3. 编写一个ResetFul API工程
  2. 3. 配置Swagger=》Config
  3. ```java
  4. package com.kuang.config;
  5. import org.springframework.context.annotation.Configuration;
  6. import springfox.documentation.swagger2.annotations.EnableSwagger2WebFlux;
  7. @Configuration
  8. @EnableSwagger2WebFlux
  9. public class SwaggerConfig {
  10. }
  1. 测试运行

配置Swagger

Swagger的bean示例Docket