spring+ehcache之基于注解方式详解

it2022-05-05  162

之前写了ssm基于ehcache的配置详解和使用,这里写下基于spring注解方式的使用和详解。

在ssm中如果想使用注解方式,那么需要在配置文件中开启注解支持:

<!--开启缓存的注解功能,否则注解无法生效--> <cache:annotation-driven /> <!-- 声明缓存管理器 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">     <property name="cacheManager" ref="ehCacheFactory"></property> </bean> <!--指定工厂类及ehcache.xml文件位置--> <bean id="ehCacheFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">     <property name="configLocation" value="classpath:ehcache.xml"/> </bean> 关于ehcache如何配置可看下我之前写的博客,这里就不写了。

 

spring注解为我们提供了三个注解分别为:

@Cacheable //缓存结果

@CachePut //添加到制定缓存

@CacheEvict //清除缓存

 @Caching //spring3.1以后的复合注解,可以批量操作缓存注解

其实在spring3.1之前还有一个注解,后来被废弃了就是:@TriggersRemove  //从缓存中移除对象

spring提供的三个注解中存在的属性:

value:必填属性,指定缓存名称,用于操作缓存

condition:非必填,基于springEL表达式进行缓存操作的限制,一般用于Cacheable注解

allEntries:boolean类型,默认false,表示是否清除所有缓存元素

beforeInvocation:boolean类型,非必填,表示清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

注意我们也可以使用ehcache的去除策略最近使用(LRU)"策略,其它还有先入先出FIFO,最少使用LFU,较少使用LRU

另外,spring内置了root对象来辅助我们使用缓存:

methodName   当前方法名    #root.methodName method    当前方法     #root.method.name target    当前被调用的对象     #root.target targetClass     当前被调用的对象的class      #root.targetClass args    当前方法参数组成的数组     #root.args[0] caches     当前被调用的方法使用的Cache    #root.caches[0].name

注意:所有注解均是基于方法的,要知道springMVC的理念就是面向方法

@Cacheable常用方式:

@Cacheable({"cache1", "cache2"})  //缓存到cache1和cache2中 @Cacheable(value="users", key="#id")  //缓存到users中key为其结果ID @Cacheable(value = "employee", condition = "#age < 25")//缓存到employee中,过滤结果集中age字段值小于25的数据 @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")//同上,取模

@Cacheable(value = {"cache1"}, key = "#root.targetClass")// key 当前类,使用root内置对象

该方法一般使用在查询操作上

@CachePut常用方式:

@CachePut(value = "lt.ecache", key = "#id") public Employee updateEmployee(Employee em)

//@CachePut将在执行完方法后(#result就能拿到返回值了)判断unless,如果返回false,则放入缓存;(即跟condition相反)

@CachePut(value = "user", key = "#user.id", unless = "#result.username eq 'zhang'")  public User conditionSave2(final User user)

该方法一般使用在更新操作上

@CacheEvict常用方式:

@CacheEvict(value = "lt.ecache", key = "#id") public Employee removeEmployee(int id, List<Employee> employees)

// beforeInvocation=false表示在方法执行之后调用(#result能拿到返回值了);且判断condition,如果返回true,则移除缓存;

@CacheEvict(value = "user", key = "#user.id", beforeInvocation = false, condition = "#result.username ne 'zhang'") public User conditionDelete(final User user)

 

@Caching示例:

 @Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。

   @Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),

         @CacheEvict(value = "cache3", allEntries = true) })

   public User find(Integer id) {

      returnnull;

   }

 

感兴趣的也可以使用自定义注解:

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Cacheable(value="users")

public @interface MyCacheable {

}

       那么在我们需要缓存的方法上使用@MyCacheable进行标注也可以达到同样的效果。

   @MyCacheable

   public User findById(Integer id) {

      return user;

   }

以上注解方式均是spring在管理维护,该注解需要我们提供缓存的支持,我这里使用的是ehcache,当然spring也支持redis,个人写的有相关文章可以查看。redis文章中提到了缓存策略,同样ssm中的ehcache也有缓存策略。

 

默认的key生成策略是通过KeyGenerator生成的,其默认策略如下    如果方法没有参数,则使用0作为key。    如果只有一个参数的话则使用该参数作为key    如果参数多余一个的话则使用所有参数的hashCode作为key。        如果我们需要指定自己的默认策略的话,那么我们可以实现自己的KeyGenerator,然后指定我们的Spring Cache使用的KeyGenerator为我们自己定义的KeyGenerator。        使用基于注解的配置时是通过cache:annotation-driven指定的.    <cache:annotation-driven key-generator="userKeyGenerator"/>    <bean id="userKeyGenerator" class="com.xxx.cache.UserKeyGenerator"/>

       而使用基于XML配置时是通过cache:advice来指定的。    <cache:advice id="cacheAdvice" cache-manager="cacheManager" key-generator="userKeyGenerator">    </cache:advice>

       需要注意的是此时我们所有的Cache使用的Key的默认生成策略都是同一个KeyGenerator。

具体策略使用方法根据个人情况而定,可自行查找资料。

使用注解方式可以避免我在上一篇ehcache文章中遗留的事务疑问。

其实ehcache内部也有事务机制,感兴趣的可以深究一下文章:https://www.cnblogs.com/yaohonv/archive/2012/02/10/JTA-Ehcache.html

 

如有不足或错误,请各位大佬指点

 


最新回复(0)