• 缓存


      Spring对缓存的支持有两种方式:注解驱动的缓存;XML声明的缓存。

      使用Spring的缓存抽象时,最为通用的方式就是在方法上添加@Cacheable和@CacheEvict注解。

    通过注解配置缓存

    @Configuration
    @EnableCaching
    public class CachingConfig{
        
        @Bean
        public CacheManager cacheManager(){
            return new ConcurrentMapCacheManager();
        }
    }

    通过XML配置缓存

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/cache
                    http://www.springframework.org/schema/cache/spring-cache.xds">
      <cache:annontation-driven />
      <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager"/>
    </beans>

      @EnableCaching和<cache:annontation-driven>工作方式是相同的。它们会创建一个切面并触发Spring缓存注解的切点。根据所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值。

      Spring3.1内置了五个缓存管理器的实现:SimpleCacheManager、NoOpCacheManager、ConcurrentMapCacheManager、CompositeCacheManager和EnCacheCacheManager。

      Spring Data提供了两个缓存管理器:RedisCacheManager和GemfireCacheManager

    Ehcache缓存

      

    @Configuration
    @EnableCaching
    public class CachingConfig{
        @Bean
        public EhCacheCacheManager cacheManager(CacheManager cm){
            return new EhCacheCacheManager(cm);
        }
    
        @Bean
        public EhCacheManagerFactoryBean ehcache(){
            EhCacheManagerFactoryBean ehCacheFactoryBean = new EhCachaManagerFactoryBean();
            ehCacheFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
            return ehCacheFactoryBean;
        }
    }

      cacheManager()方法创建了一个EhCacheManager的实例,通过传入Ehcache CacheManager实例实现的。EhCache的CacheManager要被注入到Spring的EhCacheCacheManager之中。Spring提供EhCacheManagerFactoryBean来生成EhCache的CacheManager。方法ehcache()会创建并返回一个EhCacheManagerFactoryBean实例。

      EhCache为XML定义了自己的配置模式。

      

    <ehcache>
        <cache name="cachename" maxBytesLocalHelp="50m" timeToLiveSeconds="100" />
    </ehcache>

    使用Redis缓存

      Redis可以用来为Spring缓存抽象机制存储缓存条目,Spring Data Redis提供了RedisCacheManager,这是CacheManager的一个实现。RedisCacheManager会与一个Redis服务器协作,并通过RedisTemplate将缓存条目存储到Redis中。

    @Configuration
    @EnableCaching
    public class CachingConfig{
        @Bean
        public CacheManager cacheManager(RedisTemplate redisTemplate){
            return new RedisCacheManager(redisTemplate);
        }
    
        @Bean
        public JedisConnectionFactory redisConnectionFactory(){
            JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
            jedisConnectionFactory.afterPropertiesSet();
            return jedisConnectionFactory;
        }
    
        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisCF){
            RedisTemplate<String, String> redisTemplate = new RedisTemplate<String, String>();
            redisTemplate.setConnectionFactory(redisCF);
            redisTemplate.afterPropertiesSet();
            return redisTemplate;
        }
    }

    CompositeCacheManager

      CompositeCacheManager要通过一个或多个缓存管理器来进行配置,它会迭代这些缓存管理器,以查找之前所缓存的值。

    @Bean
    public CacheManager cacheManager(net.sf.ehcache.CacheManager cm. javax.cache.CacheManager jcm){
        CompositeCacheManager cacheManager = new CompositeCacheManager();
        List<CacheManager> managers = new ArrayList<CacheManager>();
        managers.add(new JCacheCacheManager(jcm));
        managers.add(new EhCacheCacheManager(cm));
        managers.add(new RedisCacheManager(redisTemplate()));
        cacheManager.setCacheManagers(managers);
        return cacheManager;
    }

      当查找缓存条目时,CompositeCacheManager首先会从JCacheCacheManager开始检查JCache实现,然后通过EhCacheCacheManager检查Ehcache,最后使用RedisCacheManager来检查Redis完成缓存条目的查找。

      Spring提供了四个注解来声明缓存规则。这四个注解可以运用在方法或类上。当将其放在单个方法上时,注解所描述的缓存行为只会运用到这个方法上。如果注解放到类几倍时,缓存行为就会应用到这个类的所以方法上。

      @Cacheable  表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。

      @CachePut   表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法使用都会被调用

      @CacheEvict  表明Srping应该在缓存中清楚一个或多个条目

      @Caching     这是一个分组的注解,能够同时应用多个其他的缓存注解  

      @Cacheable和@CachePut都可以填充缓存。它们有一些共同属性:value(String[])要使用的缓存的名称;condition(String)SpEL表达式,如果值是false,不会将缓存应用到方法调用之上;key(String)SpEL表达式,用来计算自定义的缓存key;unless(String)SpEL表达式,如果得到的值是true,返回值不会放到缓存之中

    @Cacheable("user")
    public User findOne(long id){
        try{
            return jdbcTemplate.queryForObject(SELECT_USER_BY_ID, new User(), id);
        }catch(EmptyResultDataAccessException e){
            return null;            
        }
    }

    自定义缓存Key

      @Cacheable和@CachePut可以用key属性替换默认的key,他是通过一个SpEL表达式计算得到的。

      Spring提供了多个用来定义缓存规则的SpEL扩展

        #root.args        传递给缓存方法的参数,形式为数组

        #root.caches        该方法执行时所对应的缓存,形式为数组

        #root.target         目标对象

        #root.targetClass     目标对象的类,是#root.target.class的简写形式

        #root.method       缓存方法

        #root.methodName      缓存方法的名字,是#root.method.name的简写形式

        #result           方法调用的返回值(不能用在@Cacheable注解上)

        #Argument        任意的方法参数名或参数索引

    @CachePut(value="user", key="#user.id")
    User save(User user);

    条件化缓存

      @Cacheable和@CachePut提供了两个属性用于实现条件化缓存:unless和condition。这两个属性会接受一个SpEL表达式,如果unless属性的SpEL表达式计算结果为true,那么缓存方法返回的数据就不会放到缓存之中。如果condition属性的SpEL表达式计算结果为false,那么对于这个方法的缓存就会被禁用掉。unless只能阻止对象放进缓存,若调用该方法,依然会去缓存中进行查找,如果是找到了匹配的值,就返回找到的值。如果condition的表达式是false,在这个方法中,缓存是被禁用的,也就是说不会去缓存中查找,并且返回值也不会放进缓存中。

    @Cacheable(value="user", unless="#resule.role.contains('Admin')", condition="#id >=10" )
    User findOne(long id);

    移除缓存条目

      @CacheEvict表示当缓存值不再合法时,将其从缓存中移除。最常用在remove语句中  

        @CacheEvict("user")

        void remove(long userId);

      @Cacheable和@CachePut只能作用在非void返回值的方法上,@CacheEvict可以作用在任意的方法上。@CacheEvict有以下几个属性:  

      value      String[]  要使用的缓存名称

      key        String     SePL表达式,用来计算自定义的缓存key

      condition    String     SpEL表达式,如果得到的值是false,缓存不会应用到方法调用上

      allEntries  boolean  若为true,特定缓存的所有条目都会被移除掉

      beforeInvocation boolean  若为true,在方法调用之前移除条目,若为false,在方法调用之后再移除条目

    使用XML声明缓存

      一般有两个原因会使用XML声明缓存:可能觉得在自己的源码中添加Spring的注解不舒服和需要在没有源码的bean上应用缓存功能。

      Spring的cache命名空间提供了使用XML声明缓存规则的方法,可以作为面向注解缓存的替代方案。因为缓存是一种面向切面的行为,所以cache命名空间会与Spring的aop命名空间结合起来使用,用来声明缓存所应用的切点在哪里

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/cache
                    http://www.springframework.org/schema/cache/spring-cache.xds
                   http://www.springframework.org/schema/aop
                   http://www.springframework.org/schema/spring-aop.xsd">
     
    </beans>

    cache命名空间定义了在Spring XML配置文件中声明缓存的配置元素

      <cache:annotation-driven>  启动注解驱动的缓存,等同于Java配置中的@EnableCaching

      <cache:advice>  定义缓存通知(advice)。结合<aop:advisor>,将通知应用到切点上

      <cache:caching>  在缓存通知中,定义一组特定的缓存规则

      <cache:cacheable>  指明某个方法要进行缓存,等同于@Cacheable注解  

      <cache:cache-put>  指明某个方法要填充缓存,但不会考虑缓存中是否已有匹配的值,等同于@CachePut注解

      <cache-evict>  指明某个方法要从缓存中移除一个或多个条目,等同于@CacheEvict注解

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
                    http://www.springframework.org/schema/cache
                    http://www.springframework.org/schema/cache/spring-cache.xds
                   http://www.springframework.org/schema/aop
                   http://www.springframework.org/schema/spring-aop.xsd">
    
        <aop:config>
          <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.cherry.repository.*(..))" />
        </aop:config>
    
        <cache:advice id="cacheAdvice">
        <cache:caching>       <cache:cacheable cache="user" method="findOne"/>       <cache:cache-put cache="user" method="save" key="#reuslt.id" />       <cache:cache-evict cache="user" method="remove" />    </cache:caching>   </cache:advice>
      

      <bean id="cacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager" /> </beans>

    <cache:cache-evict>元素有两个特有的属性:

      all-entries  如果是true,缓存中所有的条目都会被移除,如果是false,只有匹配key的条目才会被移除

      before-invocation  如果是true,缓存条目将会在方法调用之前被移除,如果是false,方法调用之后才会被移除

  • 相关阅读:
    关于重载和重写的区别
    UML的关联(Association), 聚合(Aggregation), 组合(Composition)区别
    解析CSS加密技术之“障眼法”
    ASP.NET中MEMCACHED
    新建项目的无法应用已有项目
    C# 判断两张图片是否一致的快速方法
    压力测试中需要掌握的几个基本概念
    软件测试Web数据分析工具HttpWatch安装
    在SQL Server实现最短路径的搜索
    从算法入手讲解如何在SQL Server中实现最优最简
  • 原文地址:https://www.cnblogs.com/forerver-elf/p/6595837.html
Copyright © 2020-2023  润新知