介绍

 

SpringEL表达式和MVEL spring cache spel表达式_SpringEL表达式和MVEL

 常用注解

SpringEL表达式和MVEL spring cache spel表达式_缓存_02

@Cacheable

  • value、cacheNames:两个等同的参数(cacheNames为Spring 4新增,作为value的别名),用于指定缓存存储的集合名。由于Spring 4中新增了@CacheConfig,因此在Spring 3中原本必须有的value属性,也成为非必需项了
  • key:缓存对象存储在Map集合中的key值,非必需,缺省按照函数的所有参数组合作为key值,若自己配置需使用SpEL表达式,比如:@Cacheable(key = "#p0"):使用函数第一个参数作为缓存的key值,更多关于SpEL表达式的详细内容可参考官方文档
  • condition:缓存对象的条件,非必需,也需使用SpEL表达式,只有满足表达式条件的内容才会被缓存,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有当第一个参数的长度小于3的时候才会被缓存,若做此配置上面的AAA用户就不会被缓存,读者可自行实验尝试。
  • unless:另外一个缓存条件参数,非必需,需使用SpEL表达式。它不同于condition参数的地方在于它的判断时机,该条件是在函数被调用之后才做判断的,所以它可以通过对result进行判断。
  • keyGenerator:用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
  • cacheManager:用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
  • cacheResolver:用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。
    作用和配置方法:

SpringEL表达式和MVEL spring cache spel表达式_spring boot_03

 

/** * 根据ID获取Tasklog * @param id * @return */
    @Cacheable(value = CACHE_KEY, key = "#id",condition = "#result != null")
    public Tasklog findById(String id){
        System.out.println("FINDBYID");
        System.out.println("ID:"+id);
        return taskLogMapper.selectById(id);
    }

@CachePut

@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用

作用和配置方法

SpringEL表达式和MVEL spring cache spel表达式_spring_04

 

/** * 添加tasklog * @param tasklog * @return */
    @CachePut(value = CACHE_KEY, key = "#tasklog.id")
    public Tasklog create(Tasklog tasklog){
        System.out.println("CREATE");
        System.err.println (tasklog);
        taskLogMapper.insert(tasklog);
        return tasklog;
    }

@CacheEvict

@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空

作用和配置方法

SpringEL表达式和MVEL spring cache spel表达式_System_05

/** * 根据ID删除Tasklog * @param id */
    @CacheEvict(value = CACHE_KEY, key = "#id")
    public void delete(String id){
        System.out.println("DELETE");
        System.out.println("ID:"+id);
        taskLogMapper.deleteById(id);
    }

@CacheConfig

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置,@CacheConfig is a class-level annotation that allows to share the cache names,如果你在你的方法写别的名字,那么依然以方法的名字为准。
@CacheConfig是一个类级别的注解。

/** * 测试服务层 */
@Service
@CacheConfig(value = "taskLog")
public class TaskLogService {
 
    @Autowired  private TaskLogMapper taskLogMapper;
    @Autowired  private net.sf.ehcache.CacheManager cacheManager;
 
    /** * 缓存的key */
    public static final String CACHE_KEY   = "taskLog";
 
    /** * 添加tasklog * @param tasklog * @return */
    @CachePut(key = "#tasklog.id")
    public Tasklog create(Tasklog tasklog){
        System.out.println("CREATE");
        System.err.println (tasklog);
        taskLogMapper.insert(tasklog);
        return tasklog;
    }
 
    /** * 根据ID获取Tasklog * @param id * @return */
    @Cacheable(key = "#id")
    public Tasklog findById(String id){
        System.out.println("FINDBYID");
        System.out.println("ID:"+id);
        return taskLogMapper.selectById(id);
    }
}

@Caching

有时候我们可能组合多个Cache注解使用;比如用户新增成功后,我们要添加id–>user;username—>user;email—>user的缓存;此时就需要@Caching组合多个注解标签了。 

@Caching(put = {
@CachePut(value = "user", key = "#user.id"),
@CachePut(value = "user", key = "#user.username"),
@CachePut(value = "user", key = "#user.email")
})
public User save(User user) {
}

自定义缓存注解

比如之前的那个@Caching组合,会让方法上的注解显得整个代码比较乱,此时可以使用自定义注解把这些注解组合到一个注解中,如

@Caching(put = {
    @CachePut(value = "user", key = "#user.id"),
    @CachePut(value = "user", key = "#user.username"),
    @CachePut(value = "user", key = "#user.email")
})
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserSaveCache {
}

这样我们在方法上使用如下代码即可,整个代码显得比较干净。

@UserSaveCache
public User save(User user){}

如何使用

使用默认内存缓存

spring-boot-starter-web自带依赖

SpringEL表达式和MVEL spring cache spel表达式_spring_06

 

1.Springboot启动类添加注解@EnableCaching(开启缓存)

SpringEL表达式和MVEL spring cache spel表达式_SpringEL表达式和MVEL_07

 2.在对应的controller层使用缓存

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private TUserService userService;
    @Autowired
    private CacheManager cacheManager;

    @RequestMapping("tset01")
    @CachePut(value = "UserCache",key = "#user.id")
    public TUser testo1(@RequestBody TUser user) {
        System.out.println("缓存");
        userService.save(user);
        return user;
    }
}

测试结果

默认缓存(ConcurrentMapCacheManager)

没缓存时

SpringEL表达式和MVEL spring cache spel表达式_SpringEL表达式和MVEL_08

 缓存后

SpringEL表达式和MVEL spring cache spel表达式_spring boot_09

 

使用redis缓存

SpringEL表达式和MVEL spring cache spel表达式_System_10

 依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-cache -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
            <version>2.7.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>2.7.3</version>
        </dependency>

yml配置

spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
  redis:
    host: 192.168.126.129
    port: 6379
    database: 0
  cache:
    redis:
      time-to-live: 180000

开启缓存

SpringEL表达式和MVEL spring cache spel表达式_spring boot_11

 使用

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private TUserService userService;
    @Autowired
    private RedisCacheManager cacheManager;

    @RequestMapping("tset01")
    @CachePut(value = "UserCache",key = "#user.id")
    public TUser testo1(@RequestBody TUser user) {
        System.out.println("缓存");
        userService.save(user);
        return user;
    }
}

测试结果

SpringEL表达式和MVEL spring cache spel表达式_SpringEL表达式和MVEL_12