@Cacheable注解 && spel

注解参数解释:

value :缓存的名称(相当于组名),在 spring 配置文件中定义,必须指定至少一个 例如:
@Cacheable(value=”mycache”)
@Cacheable(value={”cache1”,”cache2”}

key :缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @Cacheable(value=”testcache”,key=”#userName”)

condition :缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

unless:达到此条件缓存失效。使用spel编写,返回ture不走缓存。

//key是spel编写,如果不指定,会默认所有参数的集合
//key自定义方式:一是通过参数名直接指定;
//            二是通过p+数字组合,第一个参数就是p0,以此类推
..
  @Cacheable(value="users", key="#id")
   public User find(Integer id) {
      returnnull;
   }

   @Cacheable(value="users", key="#p0")
   public User find(Integer id) {
      returnnull;
   }


   @Cacheable(value="users", key="#user.id")
   public User find(User user) {
      returnnull;
   }
   
   @Cacheable(value="users", key="#p0.id")
   public User find(User user) {
      returnnull;
   }
   //注意spel写法
   @Cacheable(value = "getAllMap", key = "'getAllMap'")
    public Optional<Map<Integer, Integer>> getAllMap() {

缓存存哪里:

查看项目CacheConfig 配置的地址
要看你自己配置的cacheManager是使用的redis还是本地存储

然后看看配置:
j2cache.properties或者redis.properties
示例:

## connection
redis.host=
redis.port=
redis.timeout=
redis.password=
redis.database=
redis.maxWait=
redis.maxTotal=
## properties
redis.maxIdle=80

##最小空闲数
redis.minIdle=10

##最大连接数:能够同时建立的“最大链接个数”
redis.maxTotal=500

#每次最大连接数
redis.numTestsPerEvictionRun=1024

##最大建立连接等待时间:单位ms
##当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
redis.maxWait=5000

##使用连接时,检测连接是否成功
redis.testOnBorrow=true

#连接耗尽时是否阻塞,false报异常,true阻塞超时,默认true
redis.blockWhenExhausted=false

##在return给pool时,是否提前进行validate操作
redis.testOnReturn=true

##当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能,单位毫秒
redis.timeout=3000

#在空闲时检查有效性,默认false
redis.testWhileIdle=true

#连接的最小空闲时间,连接池中连接可空闲的时间
redis.minEvictableIdleTimeMills=30000

#释放扫描的扫描间隔,单位毫秒数;检查一次连接池中空闲的连接,把空闲时间超过minEvictableIdleTimeMillis毫秒的连接断开,直到连接池中的连接数到minIdle为止
redis.timeBetweenEvictionRunsMillis=60000

ehcache.xml
示例:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <diskStore path="user.home"/>


    <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="30" timeToLiveSeconds="30"
                  overflowToDisk="false">
    </defaultCache>
    <!-- 
        配置自定义缓存
        maxElementsInMemory:缓存中允许创建的最大对象数
        eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
        timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
                    两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
                    如果该值是 0 就意味着元素可以停顿无穷长的时间。
        timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,
                    这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
        overflowToDisk:内存不足时,是否启用磁盘缓存。
        memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。
    -->
    <cache name="other"
           maxElementsInMemory="100000"
           overflowToDisk="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="36000"
           memoryStoreEvictionPolicy="LFU">
    </cache>
</ehcache>

补充知识点sepl


//person类

@Data
public class Person implements Serializable {
    private static final long serialVersionUID = 4305013886991449314L;
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private int age;
    private Date birthday;// 生日
    private String name;

    public Person() {
    }

    public Person(int id, String username, Date birthday) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
    }
}


//测试类
package com.zqm.controller;

import com.zqm.vo.Person;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @describe:  Spring的SpEL可以单独使用,可以使用SpEL对表达式计算、求值。SpEL主要提供了如下三个接口(位于org.springframework.expression包):
 * <p>
 * ExpressionParser:该接口的实例负责解析一个SpEL表达式,返回一个Expression对象
 * Expression:该接口的实例代表一个表达式
 * EvaluationContext:代表计算表达式值的上下文,当SpEL表达式中含有变量时,程序将需要使用该API来计算表达式的值
 *   Expression实例代表一个表达式,它包含了如下方法用于计算,得到表达式的值:
 * <p>
 * Object getValue():计算表达式的值
 * <T> T getValue(Class<T> desiredResultType):计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
 * Object getValue(EvaluationContext context):使用指定的EvaluationContext来计算表达式的值(其中EvaluationContext相当于容器包含着Expression表达式中所需要用到的值,如果是根对象,那么连对象名称都可以省略直接使用)
 * <T> T getValue(EvaluationContext context,Class<T> desiredResultType):使用指定的EvaluationContext来计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
 * Object getValue(Object rootObject):以rootObject作为表达式的root对象来计算表达式的值
 * <T> T getValue(Object rootObject,Class<T> desiredResultType):以rootObject作为表达式的root对象来计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
 * @author:zqm
 */
public class SpelTestController {


    public static void main(String[] args) {
        // 创建一个ExpressionParser对象,用于解析表达式
        ExpressionParser parser = new SpelExpressionParser();
        // 最简单的字符串表达式
        Expression exp = parser.parseExpression("'HelloWorld'");
        System.out.println("'HelloWorld'的结果: " + exp.getValue());
        // 调用方法的表达式
        exp = parser.parseExpression("'HelloWorld'.concat('!')");
        System.out.println("'HelloWorld'.concat('!')的结果: " + exp.getValue());
        // 调用对象的getter方法
        exp = parser.parseExpression("'HelloWorld'.bytes");
        System.out.println("'HelloWorld'.bytes的结果: " + exp.getValue());
        // 访问对象的属性(d相当于HelloWorld.getBytes().length)
        exp = parser.parseExpression("'HelloWorld'.bytes.length");
        System.out.println("'HelloWorld'.bytes.length的结果:" + exp.getValue());
        // 使用构造器来创建对象
        exp = parser.parseExpression("new String('helloworld')" + ".toUpperCase()");
        System.out.println("new String('helloworld')" + ".toUpperCase()的结果是: " + exp.getValue(String.class));
        Person person = new Person(1, "孙悟空", new Date());
        exp = parser.parseExpression("name");
        // 以指定对象作为root来计算表达式的值
        // 相当于调用person.name表达式的值
        System.out.println("以persn为root,name表达式的值是: " + exp.getValue(person, String.class));
        exp = parser.parseExpression("name=='孙悟空'");

        ;
// 创建一个List
        List<String> list = new ArrayList<>();
        list.add("Java");
        list.add("Spring");
// 创建一个EvaluationContext对象,作为SpEL解析变量的上下文
        EvaluationContext ctx = new StandardEvaluationContext();
// 设置一个变量
        ctx.setVariable("myList", list);
// 对集合的第一个元素进行赋值
        parser.parseExpression("#myList[0]='我爱你中国'").getValue(ctx);
// 下面测试输出
        System.out.println("List更改后的第一个元素的值为:" + list.get(0));
// 使用三目运算符
        System.out.println(parser.parseExpression("#myList.size()>3 ? 'myList长度大于3':'myList长度不大于于3'").getValue(ctx));

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值