缓存 Spring 框架提供了透明添加缓存到应用程序的支持。 只要通过使用 @EnableCaching 注解启用缓存支持,Spring Boot就会自动配置缓存基础设施。
Spring Cache Spring Boot 提供的缓存包括:JCache、Redis、Simple 等。通过 spring.cache.type 配置参数来指定缓存类型,当该值为 None 时为完全禁用缓存。
在方法上使用 @Cachable、@CacheEvict、@CachePut 表示缓存的行为。
Simple Simple 作为默认 的缓存实现,使用 ConcurrentHashMap 作为缓存存储。
Redis 如果已经引入了 spring-boot-starter-redis,缓存的配置信息可以通过 spring.cache.redis.*
来设置。
如果需要对配置信息进行更多的控制,可以考虑注册一个 RedisCacheManagerBuilderCustomizer
bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import java.time.Duration;import org.springframework.boot.autoconfigure.cache.RedisCacheManagerBuilderCustomizer;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;@Configuration(proxyBeanMethods = false) public class MyRedisCacheManagerConfiguration { @Bean public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer () { return (builder) -> builder .withCacheConfiguration("cache1" , RedisCacheConfiguration .defaultCacheConfig().entryTtl(Duration.ofSeconds(10 ))) .withCacheConfiguration("cache2" , RedisCacheConfiguration .defaultCacheConfig().entryTtl(Duration.ofMinutes(1 ))); } }
@Configuration 注解:
@Configuration 是 Spring 框架提供的一个元注解,用于表示一个类是一个配置类。
配置类通常包含 @Bean 注解,定义了创建和配置 Bean 的方法。
Spring 会扫描 @Configuration 类,并将其中的 @Bean 方法注册为 Spring 容器中的 Bean(name 默认为方法名)。
@Configuration 注解的 proxyBeanMethods 属性:用于控制@Bean方法的代理 行为,默认为 true。
当 proxyBeanMethods 属性设置为 true 时 ,Spring 会对 @Configuration 类进行 CGLIB 代理 。调用 @Bean 方法时,Spring 会检查是否已经存在该 Bean ,如果存在,则直接返回已存在的 Bean,否则调用方法创建新的 Bean 并缓存 起来。
当 proxyBeanMethods 属性设置为 false 时 ,会禁用 CGLIB 代理 。这种情况下,每一次调用 @Bean 都会执行一次方法体 ,不会缓存 Bean 对象,适用于那些需要每次返回新实例的场景 。
JetCache JetCache 是一个基于 Java 的缓存系统封装,提供统一的 API 和注解来简化缓存的使用。 JetCache 提供了比 SpringCache 更加强大的注解,可以原生的支持 TTL、两级缓存、分布式自动刷新,还提供了 Cache
接口用于手工缓存操作,支持 Spring Boot、支持统计信息。 目前有四个实现:
@EnableMethodCache、@EnableCreateCacheAnnotation 这两个注解分别激活 @Cached 和 @CreateCache 注解。也就是说,可以直接使用 @Cached 实现方法缓存,或者使用创建一个 Cache 实例两种方式,来使用 JetCache。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package com.company.mypackage;import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;import com.alicp.jetcache.anno.config.EnableMethodCache;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication @EnableMethodCache(basePackages = "com.company.mypackage") @EnableCreateCacheAnnotation public class MySpringBootApp { public static void main (String[] args) { SpringApplication.run(MySpringBootApp.class); } }
配置信息参见:https://github.com/alibaba/jetcache/blob/master/docs/CN/Config.md
创建 Cache 实例 有两种方法创建 Cache 实例,分别是 CacheManager 和 @CacheCreate 注解(在jetcache 2.7 版本CreateCache注解已经废弃)。
使用 CacheManager 可以创建 Cache 实例,area 和 name 相同的情况下,它和 Cached 注解使用同一个 Cache 实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 @Autowired private CacheManager cacheManager;private Cache<String, UserDO> userCache;@PostConstruct public void init () { QuickConfig qc = QuickConfig.newBuilder("userCache" ) .expire(Duration.ofSeconds(100 )) .cacheType(CacheType.BOTH) .syncLocal(true ) .build(); userCache = cacheManager.getOrCreateCache(qc); }
使用 @CreateCache 注解创建一个Cache实例,在jetcache 2.7 版本CreateCache注解已经废弃
1 2 @CreateCache(expire = 100) private Cache<Long, UserDO> userCache;
方法缓存 在 spring 环境下,使用 @Cached 注解可以为一个方法添加缓存,@CacheUpdate 用于更新缓存,@CacheInvalidate 用于移除缓存元素。
1 2 3 4 5 6 7 8 9 10 public interface UserService { @Cached(name="userCache.", key="#userId", expire = 3600) User getUserById (long userId) ; @CacheUpdate(name="userCache.", key="#user.userId", value="#user") void updateUser (User user) ; @CacheInvalidate(name="userCache.", key="#userId") void deleteUser (long userId) ; }
定时任务 Quartz Spring Boot 提供了 Quartz 的 starter,spring-boot-starter-quartz。如果 Quartz 可用,就会自动配置一个 Scheduler。以下类型的 Bean 会被自动装配并与 Scheduler 关联:
JobDetail
:定义了一个特定的 Job。 JobDetail
实例可以通过 JobBuilder
API建立。
Calendar
。
Trigger
:定义了一个特定的 Job 何时被触发。
定义任务 通过继承 QuartzJobBean 来定义自己的任务,重写 executeInternal 方法,并且可以通过 setter 注入属性。
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 import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import org.springframework.scheduling.quartz.QuartzJobBean;public class MySampleJob extends QuartzJobBean { private MyService myService; private String name; public void setMyService (MyService myService) { this .myService = myService; } public void setName (String name) { this .name = name; } @Override protected void executeInternal (JobExecutionContext context) throws JobExecutionException { this .myService.someMethod(context.getFireTime(), this .name); } }
持久化任务 默认情况下,使用内存中的 JobStore
。 然而,如果你的应用程序中有一个 DataSource
Bean,并且相应地配置了 spring.quartz.job-store-type
属性,也可以配置一个基于 JDBC 的 store。
要让 Quartz 使用应用程序主 DataSource
以外的 DataSource
,可以声明一个 DataSource
bean,用 @QuartzDataSource
注释其 @Bean
方法。这样做可以确保Quartz特定的数据源被 SchedulerFactoryBean
和schema初始化所使用。
同样地,为了让 Quartz 使用应用程序的主 TransactionManager
以外的 TransactionManager
,需要声明一个 TransactionManager
Bean,用 @QuartzTransactionManager
注释其 @Bean
方法。
默认情况下,通过配置创建的Job不会覆盖已经从持久性 JobStore 中读取的已注册Job。 要启用覆盖现有作业定义,需要设置 spring.quartz.overwrite-existing-jobs
属性。
Spring Task Spring 原生的支持定时任务功能,使用 @EnableScheduling 注解开启定时任务功能,使用 @Scheduled 注解指定定时任务。
1 2 3 4 5 6 7 @Component class MyBean { @Scheduled(cron = "1 * * * * ?") public void myTask () { } }