掘金手册:https://juejin.cn/book/6844733814560784397
工程热部署
我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大的时间,我们可以在修改代码后不重启就能生效,在 pom.xml 中添加如下配置就可以实现这样的功能,我们称之为热部署。
1 2 3 4 5 6
   |  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency>
 
 
  | 
 
IDEA设置自动热部署
seting —> 搜索compiler —> 勾选Build project automatically
然后 Shift+Ctrl+Alt+/,选择Registry回车
勾选compiler.automake.allow.when.app.running
配置文件
SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。(YML文件的扩展名可以使用.yml或者.yaml。)
yml配置文件的语法
(1)配置普通数据
1 2 3
   | 语法: key: value 示例代码:name: haohao 注意:value之前有一个空格
   | 
 
(2) 配置对象数据
1 2 3 4
   | 语法: key:  key1: value1  key2: value2
   | 
 
 示例代码:
1 2 3 4 5 6 7
   | person:  name: haohao  age: 31  addr: beijing    person: {name: haohao,age: 31,addr: beijing}  注意:key1前面的空格个数不限定,在yml语法中,相同缩进代表同一个级别
   | 
 
(3) 配置Map数据–同上面的对象写法
1 2 3 4 5 6
   | person:  name: haohao  age: 31  addr: beijing    person: {name: haohao,age: 31,addr: beijing}
   | 
 
(4) 配置数组(List、Set)数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   |  key:  - value1  - value2  或者:key: [value1,value2]
  city:  - Beijing  - Tianjin  
  city: [Guangzhou, Shenzhen]
  person:  - name: accp    age:  20  - name: zhangsan    age: 21 person: [{name:accp, age:20}, {name:zhangsan, age:21}]
   | 
 
多环境配置
为每个环境创建一个配置文件,命名必须以 application-环境 标识.properties|yml
SpringBoot 总配置文件: application.yml application.properties
开发环境配置文件: application-dev.yml application-dev.properties
测试环境配置文件: application-test.yml application-test.properties
生产环境配置文件: application-product.yml application-product.properties
在总配置文件 application.properties /application.ym中进行环境的激活
等号右边的值和配置文件的环境标识名一致, 可以更改总配置 文件的配置, 重新运行 Application,查看启动的端口及上下文根。
在总的配置文件application.properties中激活配置文件
1 2 3 4 5 6 7
   | 
 
 
 
 
  spring.profiles.active=product
 
  | 
 
配置文件与配置类的属性映射方式
Spring Boot 自定义配置 在 SpringBoot 的核心配置文件中,除了使用内置的配置项之外, 我们还可以在自定义配置,然后采用如下注解去读取配置的属性值 
- 使用注解@Value映射
我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上例如:
application.yml配置如下: 
1 2 3
   | person:  name: zhangsan  age: 18
   | 
 
 实体Bean代码如下:
1 2 3 4 5 6 7 8 9 10 11 12
   | @Controller public class QuickStartController { @Value("${person.name}") private String name; @Value("${person.age}") private Integer age; @RequestMapping("/quick") @ResponseBody public String quick(){ return "springboot 访问成功! name="+name+",age="+age; } }
 
   | 
 
 (2) @ConfigurationProperties  将整个文件映射成一个对象,用于自定义配置项比较多的情况 
通过注解@ConfigurationProperties(prefix=”配置文件中的key的前缀”)可以将配置文件中的配置自动与实体进行映射,需要定义get/set方法  
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | @Controller @ConfigurationProperties(prefix = "person") public class QuickStartController { private String name; private Integer age; @RequestMapping("/quick") @ResponseBody public String quick(){ return "springboot 访问成功! name="+name+",age="+age; } public void setName(String name) { this.name = name; }  public void setAge(Integer age) { this.age = age; } }
   | 
 
 (3)解决警告问题
1 2 3 4 5 6
   | <!--解决使用@ConfigurationProperties 注解出现警告问题--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
   | 
 
前端使用 JSP(不推荐)
springboot官方推荐使用Thymeleaf
笔记:https://pengyirui.gitee.io/posts/2d22.html
在pom.xml文件中配置以下依赖项
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | 
  <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> </dependency>
 
  <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency>
 
  <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency>
 
  | 
 
在 pom.xml 的 build 标签中要配置编译信息。
SpringBoot 要求 jsp 文件必须编译到指定的 META-INF/resources 目 录下才能访问,否则访问不到。因为Spring Boot默认是使用“Thymeleaf”视图模板的,而非“JSP”视图模板,因此JSP的支持并不在刚才加入的starter组件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
   | 
 
 
  <resources> <resource>
  <directory>src/main/webapp</directory>
  <targetPath>META-INF/resources</targetPath>
  <includes> <include>**/*.*</include> </includes> </resource> </resources>
 
  | 
 
配置 Spring MVC 的视图 展示为 jsp
1 2 3 4 5 6 7
   | 
  server.port=8090
 
  spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp
 
  | 
 
application.yml 格式的配置文件    
1 2 3 4 5
   | spring:   mvc:     view:       prefix: /WEB-INF/jsp/       suffix: .jsp
   | 
 
5.4在 src/main 下创建一个 webapp 目录
然后在该目录 下新建 index.jsp 页面 如果在 webapp 目录下右键,如果没有创建 jsp 的选项,可以在 Project Structure 中指定 webapp 为 Web Resource Directory    

5.5添加静态资源
客户端资源的默认路径为resources-static,本项目中添加如下静态资源

集成mybatis
添加起步依赖和驱动包
1 2 3 4 5 6 7 8 9 10 11
   |  <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>
  <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
 
  | 
 
添加数据源配置信息
在 Springboot 的核心配置文件 application.properties 中配 置数据源  
1 2 3 4 5 6 7 8 9 10 11 12
   |  spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/myCinema?useUnicode=true&characterEncoding=utf8 spring.datasource.username=root spring.datasource.password=
 
  mybatis.type-aliases-package=io.peng.model
  mybatis.mapper-locations=classpath:mapper/*Mapper.xml
  mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
 
  | 
 
在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解 @Mapper 
作用: mybatis 自动扫描数据持久层的映射文件及 DAO 接口的关系    
在 Mybatis 反向工程生成的 StudentMapper 接口上加一个 Mapper 注解 @Mapper 作用: mybatis 自动扫描数据持久层的映射文件及 DAO 接口的关系 
在 运 行 的 主 类 上 添 加 注 解 包 扫 描 @MapperScan(“com.abc.springboot.mapper”) 注释掉 Mapper 接口上的@Mapper 注解   
1 2 3 4 5 6 7 8 9 10 11
   | @SpringBootApplication
 
  @SpringBootApplication @MapperScan("io.peng.mycinema.mapper") public class MycinemaApplication {
      public static void main(String[] args) {         SpringApplication.run(MycinemaApplication.class, args);     } }
   | 
 
在application.properties文件设置mapper文件的路径
1
   | mybatis.mapper-locations=classpath:/mapper/*Mapper.xml
   | 
 
测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | 
  @SpringBootTest
 
  public class BookUserApplicationTest {
      @Autowired     private  UsersMapper usersMapper;
      @Test     public  void aaa(){         usersMapper.selectByCode("sam");     } }
 
  | 
 
事务支持
 Spring Boot 使用事务非常简单,底层依然采用的是 Spring 本身提 供的事务管理
 ➢ 在入口类中使用注解 @EnableTransactionManagement 开启 事务支持
 ➢ 在访问数据库的 Service 方法上添加注解 @Transactional 即可    
1 2 3 4 5 6 7
   |  @SpringBootApplication @MapperScan(basePackages = "com.powernode.mapper") @EnableTransactionManagement  public class Application {      }
 
  | 
 
Spring MVC 注解
| 注解 | 
作用 | 
| @Controller | 
控制器 | 
| @RestController | 
@Controller 与@ResponseBody 的组合注解 如果一个 Controller 类添加了@RestController,那么该 Controller 类下的所有方法都相当于添加了@ResponseBody 注解 用于返回字符串或 json 数据 | 
| @RequestMapping | 
支持Get请求和Post请求 | 
| @GetMapping | 
支持Get请求,用于查询数据 | 
| @PostMapping | 
只支持Post请求,用于增加数据 | 
| @PutMapping | 
只支持Put请求,用于修改数据 | 
| @DeleteMapping | 
只支持Delete请求,删除数据 | 
RESTful
REST(英文: Representational 表述性State Transfer,简称 REST)一种互联网软件架构设计的风格,但它并不是标准,它只是提出了一组客户端和服务器交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次, REST这个词,是Roy ThomasFielding 在他 2000 年的博士论文中提出的。任何的技术都可以实现这种理念,如果一个架构符合 REST 原则,
Spring Boot 开发 RESTFul Spring boot
开发 RESTFul 主要是几个注解实现 
@PathVariable 获取 url 中的数据 该注解是实现 RESTFul 最主要的一个注解    
 
 @PostMapping 接收和处理 Post 方式的请求 
 
 @DeleteMapping 接收 delete 方式的请求,可以使用 GetMapping 代替 
 
 @PutMapping 接收 put 方式的请求,可以用 PostMapping 代替 
 
 @GetMapping 接收 get 方式的请求
 
RESTful 的优点
➢ 轻量,直接基于 http,不再需要任何别的诸如消息协议 get/post/put/delete 为 CRUD 操作 
➢ 面向资源,一目了然,具有自解释性。 
➢ 数据描述简单,一般以 xml, json 做数据交换。
 ➢ 无状态,在调用一个接口(访问、操作资源)的时候,可以不 用考虑上下文,不用考虑当前状态,极大的降低了复杂度。
 ➢ 简单、低耦合    
RESTful 原则
➢ 增 post 请求、删 delete 请求、改 put 请求、查 get 请求
 ➢ 请求路径不要出现动词 
     例如:查询订单接口 /boot/order/1021/1(推荐)  /boot/queryOrder/1021/1(不推荐)
 ➢ 分页、排序等操作,不需要使用斜杠传参数 
      例如:订单列表接口 /boot/orders?page=1&sort=desc 一般传的参数不是数据库表的字段,可以不采用斜杠  
拦截器
直接上例子:地址拦截
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   | 
 
 
  @Component public class Login implements HandlerInterceptor {     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
                   if (user != null) {             return true;
          }else {             response.sendRedirect("XXX");             return false;         }     } }
 
  | 
 
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
   | 
 
 
 
 
 
 
 
 
 
 
 
  @Configuration public class WebConfig implements WebMvcConfigurer {     @Autowired     private Login login;
      @Override     public void addInterceptors(InterceptorRegistry registry) {         registry.addInterceptor(login)                 .addPathPatterns("/");                 .excludePathPatterns("/money/");     } }
 
 
  | 
 
定时任务
在日常的项目开发中,往往会涉及到一些需要做到定时执行的代码,例如自动将超过24小时的未付款的单改为取消状态,自动将超过14天客户未签收的订单改为已签收状态等等, Java项目中常使用的定时器有JDK Timer、Quartz、Spring Task等三种。Quartz的功能强大,配置也比较复杂,适合大型、多定时任务的项目使用。Spring Task配置较为简单轻量,需要Spring框架支持。JDK自带的定时器Timer使用灵活,配置简单,适合中小型项目。
Timer
这是java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。
1 2 3 4 5 6 7 8
   | TimerTask task=new TimerTask() {     @Override     public void run() {         System.out.println("hello,world...."+new Date());     } }; Timer timer=new Timer(); timer.schedule(task,1000,3000);
  | 
 
ScheduledExecutorService
jdk自带的一个类;是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响 。
1 2 3 4 5
   | ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();                      service.scheduleAtFixedRate(    ()->System.out.println("ScheduledExecutorService定时任务 "+new Date()), 0, 3,                       TimeUnit.SECONDS);
   | 
 
Spring Task
Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多 .在SpringBoot中已经内置集成了SpringTask,使用非常的方便快捷。
在类上@EnableScheduling,在方法@Scheduled
1 2 3 4 5 6 7 8 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>   </dependency>
 
  | 
 
代码 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | @Component @EnableScheduling public class SpringTaskDemo {
      @Scheduled(cron = "3/15 * * * * *")     public void start(){         System.out.println("----间隔计划任务----"+new Date());     }
      @Scheduled(initialDelay = 2000,fixedDelay = 10000)     public void stop(){         System.out.println("----延迟计划任务----"+new Date());     }
      @Scheduled(fixedRate = 10000)     public void delay(){         System.out.println("----固定计划任务----"+new Date());     } }
 
   | 
 
@Scheduled有三种定时任务的执行方式,包括fixedDelay、fixedRate、corn表达式,下面就分别讲讲这三种执行方式的不同。 
fixedDelay:指定两次任务执行的时间间隔(毫秒),此时间间隔指的是,前一次任务结束与下一个任务开始的间隔。如:@Scheduled(fixedDelay = 5*1000 ),表示第一个任务结束后,过5秒后,开始第二个任务。 
fixedRate:指定两次任务执行的时间间隔(毫秒),此时间间隔指的是,前一个任务开始与下一个任务开始的间隔。如:@Scheduled(fixedRate= 5*1000 ),表示第一个任务开始后(第一个任务执行时间小于5秒),第一个任务开始后的第6秒,开始第二个任务。如果第一个任务执行时间大于5秒,第一个任务结束后,直接开始第二个任务。
cron表达式(常用)
使用cron表达式进行任务的执行
cron一般是六个或七个字段,分别是: 
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 36 37 38 39 40 41 42 43 44 45 46
   | 1. Seconds (秒)  2. Minutes (分)  3. Hours (时)  4. Day (每月的第几天,day-of-month)  5. Month (月)  6. Day (每周的第几天,day-of-week)  7. Year (年 可选字段)
 
  说明 秒 :范围:0-59  分 :范围:0-59 时 :范围:0-23 天(月) :范围:1-31,但要注意一些特别的月份2月份没有只能1-28,有些月份没有31 月 :用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示 天(周):用1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示 年:范围:1970-2099   “/”:表示为“每”,如“0/10”表示每隔10分钟执行一次,“0”表示为从“0”分开始, “3/20”表示表示每隔20分钟执行一次 “?”:只用于月与周,表示不指定值 “L”:只用于月与周,5L用在月表示为每月的最后第五天;1L用在周表示每周的最后一天; “W”::表示有效工作日(周一到周五),只能出现在day-of-month,系统将在离指定日期的最近的有效工作日触发事件。例如:在 DayofMonth使用5W,如果5日是星期六,则将在最近的工作日:星期五,即4日触发。如果5日是星期天,则在6日(周一)触发;如果5日在星期一到星期五中的一天,则就在5日触发。另外一点,W的最近寻找不会跨过月份  “#”:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。 “*” 代表整个时间段。
 
  例子 0 0 10,14,16 * * ? 每天上午10点,下午2点,4点 0 0/30 9-17 * * ?   朝九晚五工作时间内每半小时 0 0 12 ? * WED  表示每个星期三中午12点  0 0 12 * * ?  每天中午12点  0 15 10 ? * * ? 每天上午10:15  0 15 10 * * ?  每天上午10:15  0 15 10 * * ? * 每天上午10:15  0 15 10 * * ? 2005  2005年的每天上午10:15  0 * 14 * * ? 在每天下午2点到下午2:59期间的每1分钟  0 0/5 14 * * ? 在每天下午2点到下午2:55期间的每5分钟  0 0/5 14,18 * * ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟  0 0-5 14 * * ? 在每天下午2点到下午2:05期间的每1分钟  0 10,44 14 ? 3 WED 每年三月的星期三的下午2:10和2:44  0 15 10 ? * MON-FRI 周一至周五的上午10:15  0 15 10 15 * ? 每月15日上午10:15  0 15 10 L * ? 每月最后一日的上午10:15  0 15 10 ? * 6L 每月的最后一个星期五上午10:15  0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15  0 15 10 ? * 6#3" 每月的第三个星期五上午10:15
   | 
 
@ConfigurationProperties
根据配置文件自动配置属性
1 2 3 4 5 6
   | @ConfigurationProperties(prefix = "jwt.config") @Component public class JwtUtil {     private String signKey;     private int expireMinutes; }
   | 
 
1 2
   | jwt.config.signKey=peng jwt.config.expireMinutes=0
   | 
 
配置类
一般@Configuration注释放在类上,与@Ben搭配使用
表示启动spring立即加载
web注释
路径变量
1 2 3 4
   | @DeleteMapping("/{id}") public String delete(@PathVariable ("id") Integer id){   xxxxx }
  | 
 
入参是json
1 2 3 4
   | @PostMapping("/login") public String login(@RequestBody User user){    }
  | 
 
请求参数
1 2
   | @PostMapping String check(@RequestParam("userCoed") String userCoed);
   | 
 
返回的是json
ResponseResult
自定义ResponseResult在controller响应信息主体和自定义全局及局部异常中的实现