zoukankan      html  css  js  c++  java
  • 《Spring in action 4》(九)SpringCache

    SpringCache

    简述

    ​ Caching (缓存)可以存储经常会用到的数据,这样,每次需要的时候,这些信息都是立即可用的。这里,我们会介绍Spring的缓存抽象。SpringCache 是对缓存解决方案的抽象,
    并且它对缓存功能提供了声明式的支持,能够与多种流行的缓存实现集成。在Spring中可以使用 ConcurrentMapCacheManager 来实现简单的缓存,但是ConcurrentMapCacheManager 是基于java.util.concurrent.ConcurrentHashMap,那么这就意味着它是基于内存的,生命周期是与应用关联的,可以用于开发和测试,但是对于生产级别的大型企业级应用程序,这可能不是一个理想的选择。

    ConcurrentMapCacheManager

    • 开启EnableCaching注解,默认是没有开启的。
    • 配置CacheManager
    @Configuration
    @EnableCaching
    public class CachingConfig {
    
        /*配置缓存管理器,使用SpringCache的ConcurrentMapCacheManager*/
        @Bean
        public CacheManager cacheManager(){
            ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
            return cacheManager;
        }
    }
    

    切换成RedisCacheManager

    /*配置缓存管理器,使用Redis来进行缓存处理*/
    @Bean
    public CacheManager cacheManager2(JedisConnectionFactory
                                      jedisConnectionFactory){
      RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager
        .RedisCacheManagerBuilder
        .fromConnectionFactory(jedisConnectionFactory);
      return builder.build();
    }
    

    Spring Cache 注解

    注解声明规则

    注解 描述
    @Cacheable 表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存中的值。否则的话,这个方法就会被调用,返回值会放到缓存之中。
    @CachePut 表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法始终都会被调用
    @CacheEvict 表明Spring应该在缓存中清除一个或多个条目
    @Caching 这是一个分组的注解,能够同时应用多个其他的缓存的注解

    @Cacheable的源码

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface Cacheable {
    
    	@AliasFor("cacheNames")
    	String[] value() default {};
    	@AliasFor("value")
    	String[] cacheNames() default {};
    	String key() default "";
    	String keyGenerator() default "";
    	String cacheManager() default "";
    	String cacheResolver() default "";
    	String condition() default "";
    	String unless() default "";
    	boolean sync() default false;
    }
    

    @CachePut的源码

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    @Documented
    public @interface CachePut {
    
    	@AliasFor("cacheNames")
    	String[] value() default {};
    	@AliasFor("value")
    	String[] cacheNames() default {};
    	String key() default "";
    	String keyGenerator() default "";
    	String cacheManager() default "";
    	String cacheResolver() default "";
    	String condition() default "";
    	String unless() default "";
    }
    

    填充缓存

    ​ 我们可以看到,@Cacheable和@CachePut注解都可以填充缓存,但它们的工作方式略有不同。

    @Cacheable首先在缓存中查找条目,如果找到了匹配的条目,那么就不会对方法进行了调用。如果没有找到匹配的条目,方法会被调用并且返回值要放到缓存之中。而@CachePut并不会在缓存中查询匹配的值,目标方法总是会被调用,并将返回值添加到缓存之中。

    @Cacheable和@CachePut共有的属性

    属性 类型 描述
    value String[] 要使用的缓存名称
    condition String SpEL表达式,如果得到的值是false的话,不会将缓存应用到方法调用上
    key String SpEL表达式,用来计算自定的缓存key
    unless String SpEL表达式,如果得到的值是true的话,返回值不会放到缓存之中。

    ​ @Cacheable与@CachePut提供了两个属性用以实现条件化:unless和condition,这两个属性都接受一个SpEL表达式。如果unless属性的SpEL表示式计算结果为true,那么缓存方法返回的数据就不会放到缓存中。与之类似,如果condition属性的SpEL表达式计算结果为false,那么对于这个方法缓存就会被禁用掉。

    ​ 表面上来看,unless和condition属性做的是相同的事情。但是,这里有一点细微的差别。unless属性只能阻止将对象放进缓存,但是在这个方法调用的时候,依然会去缓存中查询,如果找到匹配的值,就会返回找到的值。与之不同的,如果condition的表达式计算结果为false,那么在这个方法调用的过程中,缓存是被禁用的。就是说,不会去缓存中查询,同时也不会将返回值放到缓存中。

    自定义缓存key

    ​ @Cacheable和@CachePut都有一个名为key的属性,这个属性能够替换默认的key,它是通过一个SpEL表达式计算得到的。任意的SpEL表达式都是可行的,但是更常见的场景是所定义的表达式与存储在缓存中的值有关,据此计算得到key。

    缓存元数据

    表达式 描述
    #root.args 传递给缓存方法的参数,形式为数组
    #root.caches 该方法执行时所对应的缓存,形式为数组
    #root.target 目标对象
    #root.targetClass 目标对象的类,是#root.target.class的简写形式
    #root.method 缓存方法
    #root.methodName 缓存方法的名字,是#root.method.name的简写形式
    #result 方法调用的返回值(不能用在@Cacheable注解上)
    #Argument 任意的方法参数名(如#argName)或参数索引(如#a0或#p0)

    移除缓存条目

    ​ @CacheEvict 并不会往缓存中添加任何东西。相反,如果带有@CacheEvict注解的方法被调用的话,那么会有一个或更多的条目会在缓存中移除。

    注意:与@Cacheable 和 @CachePut不同,@CacheEvict 能够应用在返回值为void 的方法上,而@Cacheable 和 @CachePut 需要非void的返回值,它将会作为放在缓存中的条目。因为@CacheEvict只是将条目从缓存中移除,因为它可以放在任意的方法上,甚至是void方法。

    @CacheEvict 注解的属性

    value String[] 要使用的缓存名称
    key String SpEL表示式,用来计算自定义的缓存key
    condition String SpEL表达式,如果得到的值是false的,缓存不会应用到方法调用上
    allEntries boolean 如果为true的话,特定缓存的所有条目都会被移除掉
    beforeInvocation boolean 如果为true的话,在方法调用之前移除条目。如果为false(默认值)的话,在方法成功调用之后再移除条目

    源码:

    https://gitee.com/ooyhao/JavaRepo_Public/tree/master/Spring-in-Action/spring-in-action-13

    最后

    如果觉得不错的话,那就关注一下小编哦!一起交流,一起学习

    程序yuan
  • 相关阅读:
    delphi7下调用微软的Web Services的心得
    Asp.net组件设计浅论
    STC系统烧写及STC12C5A60S2最小系统
    ENET 1.3.3 VC2005 下使用
    ENet library compilation record
    51定时器
    可靠的UDP编程(ENET库)
    ASP.NET MVC3布局页与分布页调用方式概述
    排除JQuery通过HttpGet调用WebService返回Json时“parserror”错误
    AJAX数据源协调处理思路
  • 原文地址:https://www.cnblogs.com/ooyhao/p/11561880.html
Copyright © 2011-2022 走看看