SpringBoot实用开发篇第五章(整合第三方技术,jetcache,j2cache,Task)

本文涉及的产品
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
云原生内存数据库 Tair,内存型 2GB
简介: SpringBoot实用开发篇第五章(整合第三方技术,jetcache,j2cache,Task)

一、SpringBoot整合jetcache缓存

目前我们使用的缓存都是要么A要么B,能不能AB一起用呢?这一节就解决这个问题。springboot针对缓存的整合仅仅停留在用缓存上面,如果缓存自身不支持同时支持AB一起用,springboot也没办法,所以要想解决AB缓存一起用的问题,就必须找一款缓存能够支持AB两种缓存一起用,有这种缓存吗?还真有,阿里出品,jetcache。

jetcache严格意义上来说,并不是一个缓存解决方案,只能说他算是一个缓存框架,然后把别的缓存放到jetcache中管理,这样就可以支持AB缓存一起用了。并且jetcache参考了springboot整合缓存的思想,整体技术使用方式和springboot的缓存解决方案思想非常类似。下面咱们就先把jetcache用起来,然后再说它里面的一些小的功能。

做之前要先明确一下,jetcache并不是随便拿两个缓存都能拼到一起去的。目前jetcache支持的缓存方案本地缓存支持两种,远程缓存支持两种,分别如下:

本地缓存(Local)
  LinkedHashMap
  Caffeine
远程缓存(Remote)
  Redis
  Tair

二、纯远程方案

步骤①:导入springboot整合jetcache对应的坐标starter,当前坐标默认使用的远程方案是redis

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.2</version>
</dependency>

步骤②:远程方案基本配置

jetcache:
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

其中poolConfig是必配项,否则会报错

步骤③:启用缓存,在引导类上方标注注解@EnableCreateCacheAnnotation配置springboot程序中可以使用注解的形式创建缓存

@SpringBootApplication
//jetcache启用缓存的主开关
@EnableCreateCacheAnnotation
public class Springboot20JetCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot20JetCacheApplication.class, args);
    }
}

步骤④:创建缓存对象Cache,并使用注解@CreateCache标记当前缓存的信息,然后使用Cache对象的API操作缓存,put写缓存,get读缓存。

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;
    
    @CreateCache(name="jetCache_",expire = 10,timeUnit = TimeUnit.SECONDS)
    private Cache<String ,String> jetCache;
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        jetCache.put(tele,code);
        return code;
    }
    public boolean checkCode(SMSCode smsCode) {
        String code = jetCache.get(smsCode.getTele());
        return smsCode.getCode().equals(code);
    }
}

通过上述jetcache使用远程方案连接redis可以看出,jetcache操作缓存时的接口操作更符合开发者习惯,使用缓存就先获取缓存对象Cache,放数据进去就是put,取数据出来就是get,更加简单易懂。并且jetcache操作缓存时,可以为某个缓存对象设置过期时间,将同类型的数据放入缓存中,方便有效周期的管理。

上述方案中使用的是配置中定义的default缓存,其实这个default是个名字,可以随便写,也可以随便加。例如再添加一种缓存解决方案,参照如下配置进行:

jetcache:
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

如果想使用名称是sms的缓存,需要再创建缓存时指定参数area,声明使用对应缓存即可

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;
    
    @CreateCache(area="sms",name="jetCache_",expire = 10,timeUnit = TimeUnit.SECONDS)
    private Cache<String ,String> jetCache;
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        jetCache.put(tele,code);
        return code;
    }
    public boolean checkCode(SMSCode smsCode) {
        String code = jetCache.get(smsCode.getTele());
        return smsCode.getCode().equals(code);
    }
}

三、纯本地方案

远程方案中,配置中使用remote表示远程,换成local就是本地,只不过类型不一样而已。

步骤①:导入springboot整合jetcache对应的坐标starter

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.2</version>
</dependency>

步骤②:本地缓存基本配置

jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson

为了加速数据获取时key的匹配速度,jetcache要求指定key的类型转换器。简单说就是,如果你给了一个Object作为key的话,我先用key的类型转换器给转换成字符串,然后再保存。等到获取数据时,仍然是先使用给定的Object转换成字符串,然后根据字符串匹配。由于jetcache是阿里的技术,这里推荐key的类型转换器使用阿里的fastjson。

步骤③:启用缓存

@SpringBootApplication
//jetcache启用缓存的主开关
@EnableCreateCacheAnnotation
public class Springboot20JetCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot20JetCacheApplication.class, args);
    }
}

步骤④:创建缓存对象Cache时,标注当前使用本地缓存

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @CreateCache(name="jetCache_",expire = 1000,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.LOCAL)
    private Cache<String ,String> jetCache;
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        jetCache.put(tele,code);
        return code;
    }
    public boolean checkCode(SMSCode smsCode) {
        String code = jetCache.get(smsCode.getTele());
        return smsCode.getCode().equals(code);
    }
}

cacheType控制当前缓存使用本地缓存还是远程缓存,配置cacheType=CacheType.LOCAL即使用本地缓存。

四、本地+远程方案

本地和远程方法都有了,两种方案一起使用如何配置呢?其实就是将两种配置合并到一起就可以了。

jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

在创建缓存的时候,配置cacheType为BOTH即则本地缓存与远程缓存同时使用。

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @CreateCache(name="jetCache_",expire = 1000,timeUnit = TimeUnit.SECONDS,cacheType = CacheType.BOTH)
    private Cache<String ,String> jetCache;
}

cacheType如果不进行配置,默认值是REMOTE,即仅使用远程缓存方案。关于jetcache的配置,参考以下信息

属性  默认值 说明
jetcache.statIntervalMinutes  0 统计间隔,0表示不统计
jetcache.hiddenPackages 无 自动生成name时,隐藏指定的包名前缀
jetcache.[local|remote].${area}.type  无 缓存类型,本地支持linkedhashmap、caffeine,远程支持redis、tair
jetcache.[local|remote].${area}.keyConvertor  无 key转换器,当前仅支持fastjson
jetcache.[local|remote].${area}.valueEncoder  java  仅remote类型的缓存需要指定,可选java和kryo
jetcache.[local|remote].${area}.valueDecoder  java  仅remote类型的缓存需要指定,可选java和kryo
jetcache.[local|remote].${area}.limit 100 仅local类型的缓存需要指定,缓存实例最大元素数
jetcache.[local|remote].${area}.expireAfterWriteInMillis  无穷大 默认过期时间,毫秒单位
jetcache.local.${area}.expireAfterAccessInMillis  0 仅local类型的缓存有效,毫秒单位,最大不活动间隔

以上方案仅支持手工控制缓存,但是springcache方案中的方法缓存特别好用,给一个方法添加一个注解,方法就会自动使用缓存。jetcache也提供了对应的功能,即方法缓存。

方法缓存

jetcache提供了方法缓存方案,只不过名称变更了而已。在对应的操作接口上方使用注解@Cached即可

步骤①:导入springboot整合jetcache对应的坐标starter

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-starter-redis</artifactId>
    <version>2.6.2</version>
</dependency>

步骤②:配置缓存

jetcache:
  local:
    default:
      type: linkedhashmap
      keyConvertor: fastjson
  remote:
    default:
      type: redis
      host: localhost
      port: 6379
      keyConvertor: fastjson
      valueEncode: java
      valueDecode: java
      poolConfig:
        maxTotal: 50
    sms:
      type: redis
      host: localhost
      port: 6379
      poolConfig:
        maxTotal: 50

由于redis缓存中不支持保存对象,因此需要对redis设置当Object类型数据进入到redis中时如何进行类型转换。需要配置keyConvertor表示key的类型转换方式,同时标注value的转换类型方式,值进入redis时是java类型,标注valueEncode为java,值从redis中读取时转换成java,标注valueDecode为java。

注意,为了实现Object类型的值进出redis,需要保障进出redis的Object类型的数据必须实现序列化接口。

@Data
public class Book implements Serializable {
    private Integer id;
    private String type;
    private String name;
    private String description;
}

步骤③:启用缓存时开启方法缓存功能,并配置basePackages,说明在哪些包中开启方法缓存

@SpringBootApplication
//jetcache启用缓存的主开关
@EnableCreateCacheAnnotation
//开启方法注解缓存
@EnableMethodCache(basePackages = "com.itheima")
public class Springboot20JetCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot20JetCacheApplication.class, args);
    }
}

步骤④:使用注解@Cached标注当前方法使用缓存

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;
    
    @Override
    @Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
    public Book getById(Integer id) {
        return bookDao.selectById(id);
    }
}

远程方案的数据同步

由于远程方案中redis保存的数据可以被多个客户端共享,这就存在了数据同步问题。jetcache提供了3个注解解决此问题,分别在更新、删除操作时同步缓存数据,和读取缓存时定时刷新数据

更新缓存

@CacheUpdate(name="book_",key="#book.id",value="#book")
public boolean update(Book book) {
    return bookDao.updateById(book) > 0;
}
删除缓存
@CacheInvalidate(name="book_",key = "#id")
public boolean delete(Integer id) {
    return bookDao.deleteById(id) > 0;
}
定时刷新缓存
@Cached(name="book_",key="#id",expire = 3600,cacheType = CacheType.REMOTE)
@CacheRefresh(refresh = 5)
public Book getById(Integer id) {
    return bookDao.selectById(id);
}

数据报表

jetcache还提供有简单的数据报表功能,帮助开发者快速查看缓存命中信息,只需要添加一个配置即可

jetcache:
  statIntervalMinutes: 1

设置后,每1分钟在控制台输出缓存数据命中信息

[DefaultExecutor] c.alicp.jetcache.support.StatInfoLogger  : jetcache stat from 2022-02-28 09:32:15,892 to 2022-    02-28 09:33:00,003
cache    |    qps|   rate|   get|    hit|   fail|   expire|   avgLoadTime|   maxLoadTime
---------+-------+-------+------+-------+-------+---------+--------------+--------------
book_    |   0.66| 75.86%|    29|     22|      0|        0|          28.0|           188
---------+-------+-------+------+-------+-------+---------+--------------+--------------

总结

jetcache是一个类似于springcache的缓存解决方案,自身不具有缓存功能,它提供有本地缓存与远程缓存多级共同使用的缓存解决方案

jetcache提供的缓存解决方案受限于目前支持的方案,本地缓存支持两种,远程缓存支持两种

注意数据进入远程缓存时的类型转换问题

jetcache提供方法缓存,并提供了对应的缓存更新与刷新功能

jetcache提供有简单的缓存信息命中报表方便开发者即时监控缓存数据命中情况

五、SpringBoot整合j2cache缓存

jetcache可以在限定范围内构建多级缓存,但是灵活性不足,不能随意搭配缓存,本节介绍一种可以随意搭配缓存解决方案的缓存整合框架,j2cache。下面就来讲解如何使用这种缓存框架,以Ehcache与redis整合为例:

步骤①:导入j2cache、redis、ehcache坐标

<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-core</artifactId>
    <version>2.8.4-release</version>
</dependency>
<dependency>
    <groupId>net.oschina.j2cache</groupId>
    <artifactId>j2cache-spring-boot2-starter</artifactId>
    <version>2.8.0-release</version>
</dependency>
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

j2cache的starter中默认包含了redis坐标,官方推荐使用redis作为二级缓存,因此此处无需导入redis坐标

步骤②:配置一级与二级缓存,并配置一二级缓存间数据传递方式,配置书写在名称为j2cache.properties的文件中。如果使用ehcache还需要单独添加ehcache的配置文件

# 1级缓存
j2cache.L1.provider_class = ehcache
ehcache.configXml = ehcache.xml
# 2级缓存
j2cache.L2.provider_class = net.oschina.j2cache.cache.support.redis.SpringRedisProvider
j2cache.L2.config_section = redis
redis.hosts = localhost:6379
# 1级缓存中的数据如何到达二级缓存
j2cache.broadcast = net.oschina.j2cache.cache.support.redis.SpringRedisPubSubPolicy
 此处配置不能乱配置,需要参照官方给出的配置说明进行。例如1级供应商选择ehcache,供应商名称仅仅是一个ehcache,但是2级供应商选择redis时要写专用的Spring整合Redis的供应商类名SpringRedisProvider,而且这个名称并不是所有的redis包中能提供的,也不是spring包中提供的。因此配置j2cache必须参照官方文档配置,而且还要去找专用的整合包,导入对应坐标才可以使用。

一级与二级缓存最重要的一个配置就是两者之间的数据沟通方式,此类配置也不是随意配置的,并且不同的缓存解决方案提供的数据沟通方式差异化很大,需要查询官方文档进行设置。

步骤③:使用缓存

@Service
public class SMSCodeServiceImpl implements SMSCodeService {
    @Autowired
    private CodeUtils codeUtils;
    @Autowired
    private CacheChannel cacheChannel;
    public String sendCodeToSMS(String tele) {
        String code = codeUtils.generator(tele);
        cacheChannel.set("sms",tele,code);
        return code;
    }
    public boolean checkCode(SMSCode smsCode) {
        String code = cacheChannel.get("sms",smsCode.getTele()).asString();
        return smsCode.getCode().equals(code);
    }
}

j2cache的使用和jetcache比较类似,但是无需开启使用的开关,直接定义缓存对象即可使用,缓存对象名CacheChannel。

j2cache的使用不复杂,配置是j2cache的核心,毕竟是一个整合型的缓存框架。缓存相关的配置过多,可以查阅j2cache-core核心包中的j2cache.properties文件中的说明。如下:

#J2Cache configuration
#########################################
# Cache Broadcast Method
# values:
# jgroups -> use jgroups's multicast
# redis -> use redis publish/subscribe mechanism (using jedis)
# lettuce -> use redis publish/subscribe mechanism (using lettuce, Recommend)
# rabbitmq -> use RabbitMQ publisher/consumer mechanism
# rocketmq -> use RocketMQ publisher/consumer mechanism
# none -> don't notify the other nodes in cluster
# xx.xxxx.xxxx.Xxxxx your own cache broadcast policy classname that implement net.oschina.j2cache.cluster.ClusterPolicy
#########################################
j2cache.broadcast = redis
# jgroups properties
jgroups.channel.name = j2cache
jgroups.configXml = /network.xml
# RabbitMQ properties
rabbitmq.exchange = j2cache
rabbitmq.host = localhost
rabbitmq.port = 5672
rabbitmq.username = guest
rabbitmq.password = guest
# RocketMQ properties
rocketmq.name = j2cache
rocketmq.topic = j2cache
# use ; to split multi hosts
rocketmq.hosts = 127.0.0.1:9876
#########################################
# Level 1&2 provider
# values:
# none -> disable this level cache
# ehcache -> use ehcache2 as level 1 cache
# ehcache3 -> use ehcache3 as level 1 cache
# caffeine -> use caffeine as level 1 cache(only in memory)
# redis -> use redis as level 2 cache (using jedis)
# lettuce -> use redis as level 2 cache (using lettuce)
# readonly-redis -> use redis as level 2 cache ,but never write data to it. if use this provider, you must uncomment `j2cache.L2.config_section` to make the redis configurations available.
# memcached -> use memcached as level 2 cache (xmemcached),
# [classname] -> use custom provider
#########################################
j2cache.L1.provider_class = caffeine
j2cache.L2.provider_class = redis
# When L2 provider isn't `redis`, using `L2.config_section = redis` to read redis configurations
# j2cache.L2.config_section = redis
# Enable/Disable ttl in redis cache data (if disabled, the object in redis will never expire, default:true)
# NOTICE: redis hash mode (redis.storage = hash) do not support this feature)
j2cache.sync_ttl_to_redis = true
# Whether to cache null objects by default (default false)
j2cache.default_cache_null_object = true
#########################################
# Cache Serialization Provider
# values:
# fst -> using fast-serialization (recommend)
# kryo -> using kryo serialization
# json -> using fst's json serialization (testing)
# fastjson -> using fastjson serialization (embed non-static class not support)
# java -> java standard
# fse -> using fse serialization
# [classname implements Serializer]
#########################################
j2cache.serialization = json
#json.map.person = net.oschina.j2cache.demo.Person
#########################################
# Ehcache configuration
#########################################
# ehcache.configXml = /ehcache.xml
# ehcache3.configXml = /ehcache3.xml
# ehcache3.defaultHeapSize = 1000
#########################################
# Caffeine configuration
# caffeine.region.[name] = size, xxxx[s|m|h|d]
#
#########################################
caffeine.properties = /caffeine.properties
#########################################
# Redis connection configuration
#########################################
#########################################
# Redis Cluster Mode
#
# single -> single redis server
# sentinel -> master-slaves servers
# cluster -> cluster servers (数据库配置无效,使用 database = 0)
# sharded -> sharded servers  (密码、数据库必须在 hosts 中指定,且连接池配置无效 ; redis://user:password@127.0.0.1:6379/0)
#
#########################################
redis.mode = single
#redis storage mode (generic|hash)
redis.storage = generic
## redis pub/sub channel name
redis.channel = j2cache
## redis pub/sub server (using redis.hosts when empty)
redis.channel.host =
#cluster name just for sharded
redis.cluster_name = j2cache
## redis cache namespace optional, default[empty]
redis.namespace =
## redis command scan parameter count, default[1000]
#redis.scanCount = 1000
## connection
# Separate multiple redis nodes with commas, such as 192.168.0.10:6379,192.168.0.11:6379,192.168.0.12:6379
redis.hosts = 127.0.0.1:6379
redis.timeout = 2000
redis.password =
redis.database = 0
redis.ssl = false
## redis pool properties
redis.maxTotal = 100
redis.maxIdle = 10
redis.maxWaitMillis = 5000
redis.minEvictableIdleTimeMillis = 60000
redis.minIdle = 1
redis.numTestsPerEvictionRun = 10
redis.lifo = false
redis.softMinEvictableIdleTimeMillis = 10
redis.testOnBorrow = true
redis.testOnReturn = false
redis.testWhileIdle = true
redis.timeBetweenEvictionRunsMillis = 300000
redis.blockWhenExhausted = false
redis.jmxEnabled = false
#########################################
# Lettuce scheme
#
# redis -> single redis server
# rediss -> single redis server with ssl
# redis-sentinel -> redis sentinel
# redis-cluster -> cluster servers
#
#########################################
#########################################
# Lettuce Mode
#
# single -> single redis server
# sentinel -> master-slaves servers
# cluster -> cluster servers (数据库配置无效,使用 database = 0)
# sharded -> sharded servers  (密码、数据库必须在 hosts 中指定,且连接池配置无效 ; redis://user:password@127.0.0.1:6379/0)
#
#########################################
## redis command scan parameter count, default[1000]
#lettuce.scanCount = 1000
lettuce.mode = single
lettuce.namespace =
lettuce.storage = hash
lettuce.channel = j2cache
lettuce.scheme = redis
lettuce.hosts = 127.0.0.1:6379
lettuce.password =
lettuce.database = 0
lettuce.sentinelMasterId =
lettuce.maxTotal = 100
lettuce.maxIdle = 10
lettuce.minIdle = 10
# timeout in milliseconds
lettuce.timeout = 10000
# redis cluster topology refresh interval in milliseconds
lettuce.clusterTopologyRefresh = 3000
#########################################
# memcached server configurations
# refer to https://gitee.com/mirrors/XMemcached
#########################################
memcached.servers = 127.0.0.1:11211
memcached.username =
memcached.password =
memcached.connectionPoolSize = 10
memcached.connectTimeout = 1000
memcached.failureMode = false
memcached.healSessionInterval = 1000
memcached.maxQueuedNoReplyOperations = 100
memcached.opTimeout = 100
memcached.sanitizeKeys = false

总结

j2cache是一个缓存框架,自身不具有缓存功能,它提供多种缓存整合在一起使用的方案

j2cache需要通过复杂的配置设置各级缓存,以及缓存之间数据交换的方式

j2cache操作接口通过CacheChannel实现

六、Quartz任务技术

springboot整合第三方技术第二部分我们来说说任务系统,其实这里说的任务系统指的是定时任务。定时任务是企业级开发中必不可少的组成部分,诸如长周期业务数据的计算,例如年度报表,诸如系统脏数据的处理,再比如系统性能监控报告,还有抢购类活动的商品上架,这些都离不开定时任务。本节将介绍两种不同的定时任务技术。

Quartz

Quartz技术是一个比较成熟的定时任务框架,怎么说呢?有点繁琐,用过的都知道,配置略微复杂。springboot对其进行整合后,简化了一系列的配置,将很多配置采用默认设置,这样开发阶段就简化了很多。再学习springboot整合Quartz前先普及几个Quartz的概念。

工作(Job):用于定义具体执行的工作
工作明细(JobDetail):用于描述定时工作相关的信息
触发器(Trigger):描述了工作明细与调度器的对应关系
调度器(Scheduler):用于描述触发工作的执行规则,通常使用cron表达式定义规则

简单说就是你定时干什么事情,这就是工作,工作不可能就是一个简单的方法,还要设置一些明细信息。工作啥时候执行,设置一个调度器,可以简单理解成设置一个工作执行的时间。工作和调度都是独立定义的,它们两个怎么配合到一起呢?用触发器。完了,就这么多。下面开始springboot整合Quartz。

步骤①:导入springboot整合Quartz的starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

步骤②:定义任务Bean,按照Quartz的开发规范制作,继承QuartzJobBean

public class MyQuartz extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("quartz task run...");
    }
}

步骤③:创建Quartz配置类,定义工作明细(JobDetail)与触发器的(Trigger)bean

@Configuration
public class QuartzConfig {
    @Bean
    public JobDetail printJobDetail(){
        //绑定具体的工作
        return JobBuilder.newJob(MyQuartz.class).storeDurably().build();
    }
    @Bean
    public Trigger printJobTrigger(){
        ScheduleBuilder schedBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
        //绑定对应的工作明细
        return TriggerBuilder.newTrigger().forJob(printJobDetail()).withSchedule(schedBuilder).build();
    }
}

工作明细中要设置对应的具体工作,使用newJob()操作传入对应的工作任务类型即可。

触发器需要绑定任务,使用forJob()操作传入绑定的工作明细对象。此处可以为工作明细设置名称然后使用名称绑定,也可以直接调用对应方法绑定。触发器中最核心的规则是执行时间,此处使用调度器定义执行时间,执行时间描述方式使用的是cron表达式。有关cron表达式的规则,各位小伙伴可以去参看相关课程学习,略微复杂,而且格式不能乱设置,不是写个格式就能用的,写不好就会出现冲突问题。

总结

springboot整合Quartz就是将Quartz对应的核心对象交给spring容器管理,包含两个对象,JobDetail和Trigger对象
JobDetail对象描述的是工作的执行信息,需要绑定一个QuartzJobBean类型的对象
Trigger对象定义了一个触发器,需要为其指定绑定的JobDetail是哪个,同时要设置执行周期调度器

七、SpringBoot整合Task

spring根据定时任务的特征,将定时任务的开发简化到了极致。怎么说呢?要做定时任务总要告诉容器有这功能吧,然后定时执行什么任务直接告诉对应的bean什么时间执行就行了,就这么简单,一起来看怎么做

步骤①:开启定时任务功能,在引导类上开启定时任务功能的开关,使用注解@EnableScheduling

@SpringBootApplication
//开启定时任务功能
@EnableScheduling
public class Springboot22TaskApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot22TaskApplication.class, args);
    }
}

步骤②:定义Bean,在对应要定时执行的操作上方,使用注解@Scheduled定义执行的时间,执行时间的描述方式还是cron表达式

@Component
public class MyBean {
    @Scheduled(cron = "0/1 * * * * ?")
    public void print(){
        System.out.println(Thread.currentThread().getName()+" :spring task run...");
    }
}

完事,这就完成了定时任务的配置。总体感觉其实什么东西都没少,只不过没有将所有的信息都抽取成bean,而是直接使用注解绑定定时执行任务的事情而已。

如何想对定时任务进行相关配置,可以通过配置文件进行

spring:
  task:
    scheduling:
      pool:
        size: 1             # 任务调度线程池大小 默认 1
      thread-name-prefix: ssm_        # 调度线程名称前缀 默认 scheduling-      
        shutdown:
          await-termination: false    # 线程池关闭时等待所有任务完成
          await-termination-period: 10s # 调度线程关闭前最大等待时间,确保最后一定关闭


相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
消息中间件 缓存 监控
21 0
|
14天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
43 2
|
15天前
|
NoSQL 前端开发 Java
使用 Spring Boot + Neo4j 实现知识图谱功能开发
在数据驱动的时代,知识图谱作为一种强大的信息组织方式,正逐渐在各个领域展现出其独特的价值。本文将围绕使用Spring Boot结合Neo4j图数据库来实现知识图谱功能开发的技术细节进行分享,帮助读者理解并掌握这一技术栈在实际项目中的应用。
74 4
|
17天前
|
IDE Java 开发工具
还在为繁琐的配置头疼吗?一文教你如何用 Spring Boot 快速启动,让开发效率飙升,从此告别加班——打造你的首个轻量级应用!
【9月更文挑战第2天】Spring Boot 是一款基于 Spring 框架的简化开发工具包,采用“约定优于配置”的原则,帮助开发者快速创建独立的生产级应用程序。本文将指导您完成首个 Spring Boot 项目的搭建过程,包括环境配置、项目初始化、添加依赖、编写控制器及运行应用。首先需确保 JDK 版本不低于 8,并安装支持 Spring Boot 的现代 IDE,如 IntelliJ IDEA 或 Eclipse。
54 5
|
19天前
|
Java 数据库连接 数据库
告别繁琐 SQL!Hibernate 入门指南带你轻松玩转 ORM,解锁高效数据库操作新姿势
【8月更文挑战第31天】Hibernate 是一款流行的 Java 持久层框架,简化了对象关系映射(ORM)过程,使开发者能以面向对象的方式进行数据持久化操作而无需直接编写 SQL 语句。本文提供 Hibernate 入门指南,介绍核心概念及示例代码,涵盖依赖引入、配置文件设置、实体类定义、工具类构建及基本 CRUD 操作。通过学习,你将掌握使用 Hibernate 简化数据持久化的技巧,为实际项目应用打下基础。
40 0
|
19天前
|
数据库 开发者 Java
颠覆传统开发:Hibernate与Spring Boot的集成,让你的开发效率飞跃式提升!
【8月更文挑战第31天】在 Java 开发中,Spring Boot 和 Hibernate 已成为许多开发者的首选技术栈。Spring Boot 简化了配置和部署过程,而 Hibernate 则是一个强大的 ORM 框架,用于管理数据库交互。将两者结合使用,可以极大提升开发效率并构建高性能的现代 Java 应用。本文将通过代码示例展示如何在 Spring Boot 项目中集成 Hibernate,并实现基本的数据库操作,包括添加依赖、配置数据源、创建实体类和仓库接口,以及在服务层和控制器中处理 HTTP 请求。这种组合不仅简化了配置,还提供了一套强大的工具来快速开发现代 Java 应用程序。
29 0
|
19天前
|
Java 前端开发 Spring
技术融合新潮流!Vaadin携手Spring Boot、React、Angular,引领Web开发变革,你准备好了吗?
【8月更文挑战第31天】本文探讨了Vaadin与Spring Boot、React及Angular等主流技术栈的最佳融合实践。Vaadin作为现代Java Web框架,与其他技术栈结合能更好地满足复杂应用需求。文中通过示例代码展示了如何在Spring Boot项目中集成Vaadin,以及如何在Vaadin项目中使用React和Angular组件,充分发挥各技术栈的优势,提升开发效率和用户体验。开发者可根据具体需求选择合适的技术组合。
28 0
|
21天前
|
前端开发 Java 开发者
Spring Boot DevTools 热部署神器,助你在开发浪潮中乘风破浪,一骑绝尘!
【8月更文挑战第29天】在快速迭代的软件开发领域,高效开发至关重要。Spring Boot DevTools 作为一款优秀的热部署工具,可自动重新加载代码修改,无需手动重启应用,大幅节省时间,即时预览修改效果,简化开发流程。通过简单示例,展示了其自动刷新静态资源和模板文件的功能,有效提升了开发效率,使开发者更专注于功能实现。它就像是开发者的得力助手,显著减少等待时间,带来更高效、流畅的开发体验。
29 0
|
21天前
|
缓存 Java 数据库连接
Spring Boot 资源文件属性配置,紧跟技术热点,为你的应用注入灵动活力!
【8月更文挑战第29天】在Spring Boot开发中,资源文件属性配置至关重要,它让开发者能灵活定制应用行为而不改动代码,极大提升了可维护性和扩展性。Spring Boot支持多种配置文件类型,如`application.properties`和`application.yml`,分别位于项目的resources目录下。`.properties`文件采用键值对形式,而`yml`文件则具有更清晰的层次结构,适合复杂配置。此外,Spring Boot还支持占位符引用和其他外部来源的属性值,便于不同环境下覆盖默认配置。通过合理配置,应用能快速适应各种环境与需求变化。
27 0
|
21天前
|
XML Java 决策智能
拥抱智能决策新纪元!Spring Boot携手LiteFlow规则引擎,让复杂业务处理如丝般顺滑,引领技术潮流!
【8月更文挑战第29天】LiteFlow是一款专为Java应用设计的轻量级规则引擎,支持条件、循环、分支等多种规则类型,具有组件化设计和高度可扩展性。通过自定义规则和事件监听,它可以显著提升代码的可维护性和可重用性。本文将详细介绍如何在Spring Boot项目中整合LiteFlow,并通过实际案例演示其强大功能。主要步骤包括:添加依赖、配置参数、定义组件及流程,并通过API触发执行。借助LiteFlow,复杂业务逻辑处理变得更加灵活高效。
37 0