目录

@RequestMapping 请求映射

@SuppressWarnings 抑制警告

@Scheduled 执行定时任务

cron 表达式

@Scheduled 集群下防止重复执行


@RequestMapping 请求映射

1、@RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上,用于类上时,表示类中的所有响应请求的方法都是以该地址作为父路径。

2、@RequestMapping 注解有如下属性

属性 描述 举例
String name() default "" 为该映射指定一个名称
String[] value() default {} 指定请求的实际地址,value值前缀"/"可写可不写

@RequestMapping("/visits"),

@RequestMapping(value = {"visits1","visits2"})

String[] path() default {} 等同 value
RequestMethod[] method() default {} 指定请求的 method 类型,有 GET、POST、PUT、DELETE 等 @RequestMapping(value = "visits",method = RequestMethod.GET)
String[] params() default {} 指定 request 中必须包含某些参数值时才让该方法处理 @RequestMapping(value = "test4", params = "token", method = RequestMethod.GET)
String[] headers() default {} 指定 request中必须包含某些指定的 header 值,才能让该方法处理请求
String[] consumes() default {} 指定处理请求的提交内容类型(Content-Type),例如 application/json, text/html
String[] produces() default {} 指定返回的内容类型,仅当 request 请求头中的(Accept)类型中包含该指定类型才返回

3、举例如下:

@RestController
@RequestMapping(value = "visits")
public class VisitsController {//http://localhost:8080/visits/test1@RequestMapping(value = "test1", method = RequestMethod.GET)public String visitsTest1(HttpServletRequest request) {return request.getRequestURL().toString();}//http://localhost:8080/visits/test2, http://localhost:8080/visits/test3 都会进入@RequestMapping(value = {"test2", "test3"}, method = RequestMethod.GET)public String visitsTest23(HttpServletRequest request) {return request.getRequestURL().toString();}//http://localhost:8080/visits/test4?token=98, 请求必须携带参数 token,否则匹配不上,进入不了方法@RequestMapping(value = "test4", params = "token", method = RequestMethod.GET)public String visitsTest4(HttpServletRequest request) {return request.getRequestURL().toString();}//http://localhost:8080/visits/test5/his, http://localhost:8080/visits/test5/5x,路径结尾必须有路径变量@RequestMapping(value = "test5/{type}", method = RequestMethod.POST)public String visitsTest5(@PathVariable(value = "type") String type, HttpServletRequest request) {return request.getRequestURL().toString() + "\t" + type;}
}

src/main/java/com/wmx/yuanyuan/controller/VisitsController.java · 汪少棠/yuanyuan - Gitee.com

4、随着现在 rest 风格的流行,人们更倾向与使用简洁的 @GetMapping、@PostMapping、@DeleteMapping、@PutMapping 等注解,它们的属性与 @RequestMapping 完全一样。

@GetMapping(value = "test1") 等价于 @RequestMapping(value = "test1", method = RequestMethod.GET)
@PostMapping(value = "test5/{type}") 等价于 @RequestMapping(value = "test5/{type}", method = RequestMethod.POST)
@DeleteMapping 等价于 @RequestMapping(value = "test1", method = RequestMethod.DELETE)
@PutMapping 等价于 @RequestMapping(value = "test1", method = RequestMethod.PUT)

@SuppressWarnings 抑制警告

1、java.lang.SuppressWarnings 注解主要用在取消一些编译器产生的警告对代码左侧行列的遮挡,比如这会挡住断点调试时打的断点。

2、通过源码可知 @SuppressWarnings 其注解目标为类、字段、构造函数、方法、方法参数、方法内的局部变量。

3、@SuppressWarnings({"value1","values2"...}),其中的 value 取值如下:

public void show2() {@SuppressWarnings("unused")int a;
}
@java.lang.SuppressWarnings("unused")
public void show1() {int a;
}
@SuppressWarnings(value = {"unused","unchecked"})
public void show3() {int a;
}

3、@SuppressWarnings 抑制的警告类型如下:

警告类型 描述
all 抑制所有警告
boxing 禁止相对于装箱/取消装箱操作的警告
cast 抑制与强制转换操作相关的警告
dep-ann 禁止显示与已弃用的批注相关的警告
deprecation 取消与否决相关的警告
fallthrough 禁止显示与switch语句中缺少中断相关的警告
finally 抑制与finally块相关的不返回的警告
hiding 抑制相对于隐藏变量的局部变量的警告
incomplete-switch 禁止显示与switch语句中缺少项有关的警告(枚举情况)
nls 禁止显示与非nls字符串文本相关的警告
null 抑制与空分析相关的警告
rawtypes 对类参数使用泛型时,禁止显示与非特定类型相关的警告
restriction 抑制与使用不鼓励或禁止的引用相关的警告
serial 取消显示与可序列化类缺少串行版本uuid字段相关的警告
static-access 禁止与不正确的静态访问相关的警告
synthetic-access 禁止与来自内部类的未优化访问相关的警告
unchecked 取消显示与未检查的操作相关的警告
unqualified-field-access 取消与字段访问不合格相关的警告
unused 禁止显示与未使用的代码相关的警告
Duplicates 抑制 Found duplicate code(代码重复)的警告

@Scheduled 执行定时任务

1、@Scheduled 用在方法上,表示定时执行此方法,前提是这个类的实例需要由 Spring 容器管理,所以通常和 @Controller、@Service、@Repository、@Component 等注解一起使用。

2、如果是以前配置文件的方式,则需要在 spring 配置文件中配置扫描,而使用注解则更加简洁了。

1) Spring Boot 启动类上加上 @org.springframework.scheduling.annotation.EnableScheduling 注解,表示开启 @Scheduled2)在 @Controller、@Service、@Repository、@Component 等组件中提供 @Scheduled 方法,表示定时执行此方法3)默认情况下一个组件中的所有 @Scheduled 采用一个单线程执行,即一个 @Scheduled 执行完成后,另一个 @Scheduled 才能执行4)如果想要并发执行组件中的所有 @Scheduled,则需要在类上加上 @org.springframework.scheduling.annotation.EnableAsync 注解,在方法上再加上 @org.springframework.scheduling.annotation.Async 注解

3、环境:Java JDK 1.8,Spring Boot 2.0.3,举例如下:

3.1 启动类:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling  //开启 @Scheduled 定时任务
public class WebAppApplication {public static void main(String[] args) {SpringApplication.run(WebAppApplication.class, args);}
}

3.2 提供一个组件设置定时任务:

//1、EnableAsync:开启并发执行所有定时任务,这个不是必须的,可以不配置。
//2、EnableScheduling:开启定时任务
//3、默认情况下一个组件中的所有 @Scheduled 采用一个单线程执行,即一个 @Scheduled 执行完成后,另一个 @Scheduled 才能执行
@Component
@EnableAsync
public class SystemTimer {/*** 每隔约定时间执行一次。上一次任务执行完成如果没有超时,则会继续延迟,如果已经超时,下一次任务则会立即执行* 1、Async :并发执行此任务,这个不是必须的,可以不配置。* 2、开启异步执行时,不再有延迟的问题,因为时间一到,自动会新开线程执行任务.* 3、fixedRate、fixedDelay、cron 只能出现一个,不能同时设置。*/@Scheduled(cron = "0 0/1 * * * ?")@Asyncpublic void time1() {try {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = new Date();System.out.println("time1->" + Thread.currentThread().getName() + " -> " + dateFormat.format(date));Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}/*** 每隔 fixedDelay 毫秒执行一次。下一次会在上一次任务执行完成后,继续延迟 fixedDelay 毫秒后再执行。* 1、fixedRate、fixedDelay、cron 只能出现一个,不能同时设置。*/@Scheduled(fixedDelay = 60 * 1000)@Asyncpublic void time2() {try {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = new Date();System.out.println("time2->" + Thread.currentThread().getName() + " -> " + dateFormat.format(date));Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}/*** 每隔 fixedRate 毫秒执行一次。下一次会在上一次任务执行完成后执行,如果上一次任务执行超时,则下一次会立即执行* 1、fixedRate、fixedDelay、cron 只能出现一个,不能同时设置。*/@Scheduled(fixedRate = 60 * 1000)@Asyncpublic void time3() {try {SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date = new Date();System.out.println("time3->" + Thread.currentThread().getName() + " -> " + dateFormat.format(date));Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}}
}

cron 表达式

1、Cron 表达式是一个字符串,用空格隔开,分为6或7个域,从左到右为:秒 分 小时 月份中的日期 月份 星期中的日期 年份。年份可写可不写。

@Scheduled(cron = "0/3 * * * * ?") 每 3 秒钟执行一次
@Scheduled(cron = "0 0/30 * * * ?") 每 30 分钟在第 0 秒时刻执行一次
@Scheduled(cron = "0 0/30 0 * * * ?") 在每天 0 点内,每 30 分钟在第 0 秒时刻执行一次
@Scheduled(cron = "40 0/30 * * * ?") 每 30 分钟在第 40 秒时刻执行一次
@Scheduled(cron = "0 0 12 * * 2,6") 每周1、周5在 12:0:0 时刻执行一次

2、介绍 Cron 表达式的文章网上太多了,不再累述:

cron表达式详解 - 沧海一粟hr - 博客园 https://www.jb51.net/article/138900.htm cron表达式_一直特立独行的猫-CSDN博客 Cron表达式 - imstrive - 博客园

@Scheduled 集群下防止重复执行

1、当服务集群部署时,一旦到达指定时间,多个实例上的定时器就会同时执行任务,从而浪费资源,甚至造成重复数据或者程序异常。

2、可以考虑使用第三方的分布式定时框架,比如 Quartz,比较简单的方式是借助 redis 实现。

/*** 集群环境下防止重复执行,同一任务只允许一个实例执行* 1、执行任务的线程往 redis 中存储一个 key表示正在执行任务,其它实例则可以不用重复执行。* 2、缓存的 key 的过期时间可以根据任务执行的时间间隔来定:* * 2.1、比如任务是每天晚上 0 点执行,则过期时间设置为 1 个小时都行,因为第二天又是全新的。* * 2.2、间隔执行时,过期时间设置为间隔时间减去方法执行时间,这样即使不同实例不是同一时间启动,也能保证间隔时间内只会有一个实例执行。*/@Scheduled(cron = "0 0/1 * * * ?")@Asyncpublic void time4() {try {//定时任务执行的间隔时间(毫秒)long startTimeMillis = System.currentTimeMillis();long intervalTimeMillis = 1 * 60 * 1000;String time = DateUtil.date().toString();String cacheKey = "SystemTimer#time4";Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent(cacheKey, instanceName, intervalTimeMillis, TimeUnit.MILLISECONDS);if (ifAbsent) {System.out.println("==============" + time + " 实例【" + instanceName + "】获得执行任务权限.");//可以将任务执行的实例情况存储到 redis 中,最多记录 100条.Long leftPush = redisTemplate.opsForList().leftPush(cacheKey + "#log", time + "【" + instanceName + "】");if (leftPush > 100) {redisTemplate.opsForList().rightPop(cacheKey + "#log");}//模拟业务操作耗时.TimeUnit.MILLISECONDS.sleep(1000 + new SecureRandom().nextInt(3000));//任务执行完成时,防止下一个任务时间到了,上一个任务的 key 还没有过期。重新设置一下 key 的过期时间,因为上面 setIfAbsent 的过期时间并不包括任务执行时间.//在减去任务执行耗时的基础上,再多减去几秒,把 expire 操作的耗时也计划在内。如果过期时间低于1秒,就不再设置了。long expire = intervalTimeMillis - (System.currentTimeMillis() - startTimeMillis) - 3000;if (expire > 1000) {redisTemplate.expire(cacheKey, expire, TimeUnit.MILLISECONDS);}} else {Object value = redisTemplate.opsForValue().get(cacheKey);System.out.println("==============" + time + " 实例【" + instanceName + "】未获得执行任务权限,任务当前正在被实例【" + value + "】执行。");}} catch (Exception e) {e.printStackTrace();}}

src/main/java/com/wmx/wmxredis/schedule/SystemTimer.java · 汪少棠/wmx-redis - Gitee.com

SpingMVC 注解@RequestMapping、@SuppressWarnings、@Scheduled 定时器相关推荐

  1. 一篇文章看懂@Scheduled定时器/@Async/CompletableFuture

    一篇文章看懂@Scheduled定时器/@Async/CompletableFuture @Scheduled注解解析: 1.cron:最重要的一个参数 cron表达式[秒] [分] [小时] [日] ...

  2. 注解RequestMapping中的URI路径最前面到底需不需要加斜线?

    注解RequestMapping中的URI路径最前面到底需不需要加斜线? 您有没有这样的困惑:在协同开发过程中,使用RequestMapping,或者是GetMapping,或者是PostMappin ...

  3. 【spring学习笔记】(二)Spring MVC注解配置 参数转换注解@RequestMapping@RequestParam、@PathVariable@MatrixVariable

    @TOC 介绍 在Spring MVC项目中,<\context:component-scan>配置标签还会开启@Request-Mapping.@GetMapping等映射注解功能(也就 ...

  4. springmvc注解@RequestMapping

    springmvc注解@RequestMapping 1.处理器.controller的url 2)跟路径+子路径. 3)限定提交方法 @RequestMapping的属性method: 1.Requ ...

  5. Java中使用@Scheduled定时器操作

    在Java中使用@Scheduled定时器的几种种操作方式. 1.fixedRate 例:@Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行 2.fixe ...

  6. 注解RequestMapping中produces属性

    注解RequestMapping中produces属性可以设置返回数据的类型以及编码,可以是json或者xml:@RequestMapping(value="/xxx",produ ...

  7. 注解@RequestMapping 的 produces属性

    注解@RequestMapping 的 produces属性 指定响应体返回类型和编码格式 @RequestMapping(value = "/users",produces = ...

  8. 一步到位:依靠注解@EnableScheduling,@Scheduled 三步解决springboot定时器任务

    1.首先在spring boot项目启动上面加上@EnableScheduling注解 2.然后去到你要实现定时器任务的方法所属的类上面加上@Component注解 3.在要实现定时器任务的方法上面加 ...

  9. 电脑锁屏后一段时间,@Scheduled定时器的任务不执行

    在SpringBoot项目部署到本地计算机上时中遇到了这样的问题,Application类已经写了@EnableScheduling注解,对应的定时任务也有@Scheduled的注解,且已经使用@Co ...

  10. @Scheduled定时器

    目录 一.基本使用 二.参数详解 1. @Scheduled(fixedDelay = 5000) 2. @Scheduled(fixedRate = 5000) 3. @Scheduled(cron ...

最新文章

  1. 当AI有了情商,会说话就多说点
  2. Java异常的性能分析
  3. mysql报错1690_Mysql运行模式及1690错误处理
  4. 女黑客发现Firefox高危漏洞获奖4000美元
  5. 【解决办法】No module named 'ahocorasick'
  6. python中requests的常用方法_python3 Requests常用操作
  7. 区块链数字广告项目-【DadxChain】
  8. openSUSE 11 上的配置可以Xmanager远程桌面
  9. Anaconda安装绘图模块altair
  10. Linux基础(8)Linux常用网络命令
  11. 利用偏最小二乘法选出最重要的特征波段Matlab
  12. 美国拉斯维加斯游戏CRAPS(花旗骰)掷骰子的游戏的C语言版本
  13. 感谢同事的临别赠言,愿自己一路顺风。
  14. 【Ubuntu 20.04 LTS】设置笔记本合并盖子不休眠
  15. 鲁宾逊微积分教材版权的“知识共享”授权方式
  16. 使用硬盘从linux服务器上复制文件
  17. MYSQL 因单引号报语法错误
  18. ruby rails + grape + sidekiq 项目实践
  19. 2023年最有前景的行业
  20. Python简明教程--Set

热门文章

  1. 用Mediator Pattern + Queue 解决 订单处理流程
  2. 如何在Web App Project 或者 Web Site Project的App_Code 内使用 Profile/ProfileCommon
  3. 小波变换和motion信号处理(二)
  4. VC编程-预编译头文件(precompiled header)
  5. linux perl占用大量资源_Monitorix:一款面向Linux/Unix系统的网络监测工具
  6. L1-003 个位数统计 (15 point(s))
  7. pandas统计所有列的基础数据
  8. Caffe学习:pycaffe利用caffemodel进行分类(2)
  9. 2021-08-13servlet 原理及注意事项
  10. php move函数,php – 在null上调用成员函数move()