9月1日

/usr/local/opt/redis/bin/redis-server /usr/local/etc/redis.conf

@Cacheable 注解在方法上,表示该方法的返回结果是可以缓存的。

也就是说,该方法的返回结果会放在缓存中,以便于以后使用相同的参数调用该方法时,会返回缓存中的值,而不会实际执行该方法。

注意,这里强调了一点:参数相同。这一点应该是很容易理解的,因为缓存不关心方法的执行逻辑,它能确定的是:

对于同一个方法,如果参数相同,那么返回结果也是相同的。

@Cacheable 提供两个参数来指定缓存名:valuecacheNames,二者选其一即可。

1
2
3
4
5
6
7
8
9
@Override
@Cacheable("menu")
public Menu findById(String id) {
Menu menu = this.getById(id);
if (menu != null){
System.out.println("menu.name = " + menu.getName());
}
return menu;
}

在这个例子中,findById 方法与一个名为 menu 的缓存关联起来了。调用该方法时,会检查 menu 缓存如果缓存中有结果,就不会去执行方法了。

关联多个缓存名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
@Cacheable({"menu", "menuById"})
public Menu findById(String id) {
Menu menu = this.getById(id);
if (menu != null){
System.out.println("menu.name = " + menu.getName());
}
return menu;
}


@GetMapping("/findById/{id}")
public Menu findById(@PathVariable("id")String id){
Menu menu0 = menuService.findById("fe278df654adf23cf6687f64d1549c0a");
Menu menu2 = menuService.findById("fb6106721f289ebf0969565fa8361c75");
return menu0;
}

多个缓存,分别存的什么

@SuppressWarings注解                           

作用:用于抑制编译器产生警告信息。

@Cacheable可以标记在一个方法上,也可以标记在一个类上。

当标记在一个方法上时表示该方法是支持缓存的,当标记在一个类上时则表示该类所有的方法都是支持缓存的。

对于一个支持缓存的方法,Spring会在其被调用后将其返回值缓存起来,

以保证下次利用同样的参数来执行该方法时可以直接从缓存中获取结果,而不需要再次执行该方法。

Spring在缓存方法的返回值时是以键值对进行缓存的,值就是方法的返回结果,

至于键(key)的话,Spring又支持两种策略,默认策略自定义策略

需要注意的是当一个支持缓存的方法在 对象内部被调用时-(什么是对象内部被调用) 是不会触发缓存功能的

@Cacheable可以指定三个属性,value、key和condition。

value属性指定Cache名称

value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的

对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。

使用key属性自定义key

key属性是用来指定Spring缓存方法的返回结果时对应的key的。

该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。

我们这里先来看看自定义策略,至于默认策略会在后文单独介绍。

自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性。

使用方法参数时我们可以直接使用“**#参数名”或者“#p参数index** 如p0 p1 p2”。下面是几个使用参数作为key的示例。

当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。如:

1
2
3
4
5
6
7
@Cacheable(value={"users", "xxx"}, key="caches[1].name")

public User find(User user) {
returnnull;

}

condition属性指定发生的条件

有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。

condition属性默认为空,表示将缓存所有的调用情形。

其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理

当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。

如下示例表示只有当user的id为偶数时才会进行缓存。

@Cacheable(value={“users”}, key=”#user.id”, condition=”#user.id%2==0”)

public User find(User user) {

System.out.println(“find user by user “ + user);

return user;

}

@CachePut

在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。

@CachePut也可以声明一个方法支持缓存功能。

与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。

​ @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。

@CachePut(“users”)//每次都会执行方法,并将结果存入指定的缓存中

默认策略

​ 默认的key生成策略是通过KeyGenerator生成的,其默认策略如下:

n 如果方法没有参数,则使用0作为key。

n 如果只有一个参数的话则使用该参数作为key。

n 如果参数多余一个的话则使用所有参数的hashCode作为key。