自动建设网站系统,江西省的建设厅官方网站,住建局领导班子成员分工,吴忠公司做网站带你深入分析Spring所提供的缓存Cache管理器的实战开发指南 前提介绍基于注解的支持Cacheablecacheable的属性介绍value属性指定Cache名称使用key属性自定义key案例分析caches condition属性指定发生的条件 CachePut使用案例 CacheEvictallEntries属性beforeInvocation属性 Cac… 带你深入分析Spring所提供的缓存Cache管理器的实战开发指南 前提介绍基于注解的支持Cacheablecacheable的属性介绍value属性指定Cache名称使用key属性自定义key案例分析caches condition属性指定发生的条件 CachePut使用案例 CacheEvictallEntries属性beforeInvocation属性 CachingCaching定义如下使用案例 自定义缓存注解 前提介绍
Spring Cache是基于方法级别的其核心思想是将调用带有缓存的方法时的参数和返回结果作为键值对存储在缓存中。当下次调用相同参数的方法时直接从缓存中获取结果而不再执行该方法。因此在使用Spring Cache时需要确保被缓存的方法对于相同的参数具有相同的返回结果。
使用Spring Cache需要进行两个步骤
声明需要使用缓存的方法。配置Spring对Cache的支持。
与Spring对事务管理的支持类似Spring对Cache的支持有两种方式基于注解和基于XML配置。下面我们先来看看基于注解的方式。
基于注解的支持
Spring提供了几个注解来支持Spring Cache其中核心的注解包括Cacheable和CacheEvict。使用Cacheable标记的方法在执行后Spring Cache会缓存其返回结果而使用CacheEvict标记的方法可以在方法执行前或执行后移除Spring Cache中的某些元素。接下来我们将详细介绍Spring基于注解对Cache的支持所提供的几个注解。
Cacheable
Cacheable注解可以应用于单个方法或整个类。当应用于方法时该注解表示该方法支持缓存当应用于类时表示该类的所有方法都支持缓存。被Cacheable注解标记的方法会在调用后将返回值缓存起来这样下次使用相同参数调用该方法时可以直接从缓存中获取结果无需再次执行该方法从而提高方法的执行效率。
cacheable的属性介绍
Spring使用键值对来缓存方法的返回值。键用于检索缓存中的结果而值则是方法的返回结果。Spring支持两种缓存键的策略默认策略和自定义策略接下来将对这两种策略进行详细说明。请注意当一个支持缓存的方法在对象内部被调用时不会触发缓存功能。
Cacheable注解还提供了三个属性value、key和condition。value属性用于指定缓存的名称或命名空间可以用来区分不同缓存的作用域。key属性用于指定生成缓存键的条件可以根据方法参数或其他条件生成不同的键以实现更灵活的缓存策略。condition属性用于指定缓存的条件只有在符合条件的情况下才会进行缓存。
value属性指定Cache名称
value属性是必须指定的它表示当前方法的返回值会被缓存在哪个Cache上也就是对应的Cache的名称。可以指定一个Cache也可以指定多个Cache。当需要指定多个Cache时可以使用数组形式。
//Cache是发生在cache1上的
Cacheable(cache1)
public User find(Integer id) {Return null;
}//Cache是发生在cache1和cache2上的
Cacheable({cache1, cache2})
public User find(Integer id) {Return null;
}使用key属性自定义key
key属性用于指定Spring缓存方法返回结果时对应的key。该属性支持使用SpringEL表达式。如果未指定该属性Spring将使用默认策略生成key。
下面是一个自定义策略的示例我们可以使用SpringEL表达式来指定key。在EL表达式中我们可以使用方法参数及其属性。使用方法参数作为key时可以直接使用“#参数名”或者“#p参数索引”。
案例分析
以下是几个使用参数作为key的示例 Cacheable(valueusers, key#id)public User find(Integer id) {return null;}Cacheable(valueusers, key#p0)public User find(Integer id) {return null;}Cacheable(valueusers, key#user.id)public User find(User user) {return null;}Cacheable(valueusers, key#p0.id)public User find(User user) {return null;}除了上述使用方法参数作为key的方法外Spring还提供了一个root对象可以用来生成key。通过该root对象我们可以获取以下信息
方法名称#root.methodName可以获取当前缓存方法的名称。目标类名称#root.targetClass可以获取当前缓存方法所在的目标类的名称。目标对象#root.target可以获取当前缓存方法所在的目标对象。方法参数#root.args可以获取当前缓存方法的参数列表。
使用这些信息作为key的一部分可以更精确地指定缓存方法的返回结果所对应的key。下面是一个示例
Cacheable(value myCache, key #root.methodName : #root.targetClass : #root.args[0])
public String getSomeData(String key) {// ...
}在这个示例中使用了方法名称、目标类名称和第一个参数作为key的一部分以确保每个不同的参数组合都能生成不同的缓存key。 注意当我们要使用root对象的属性作为key时我们也可以省略“#root” caches
caches当前被调用的方法使用的Cache#root.caches[0].name因为Spring默认使用的就是root对象的属性。下面是一个示例
Cacheable(value {users, xxx}, key caches[1].name)
public User find(User user) {return null;
}在这个示例中我们使用了root对象的属性caches[1].name作为缓存的key。这意味着根据缓存的设置当调用这个方法时Spring将会使用users和xxx这两个缓存的名称以及caches[1].name作为缓存的key。
condition属性指定发生的条件
有时候我们可能不希望缓存一个方法的所有返回结果。通过condition属性我们可以实现这一功能。condition属性的默认值为空表示缓存所有的调用情况。该属性的值通过SpringEL表达式来指定当为true时表示进行缓存处理当为false时表示不进行缓存处理即每次调用该方法时都会执行一次。下面的示例展示了只有当user的id为偶数时才会进行缓存
Cacheable(value users, key #user.id, condition #user.id % 2 0)
public User find(User user) {// 方法逻辑
}在这个示例中我们使用了SpringEL表达式#user.id % 2 0作为condition属性的值。这个表达式的含义是只有当user的id是偶数时才会进行缓存。如果user的id是奇数则每次调用find()方法时方法都会执行一次而不会使用缓存的结果。
CachePut
CachePut注解也可以用来声明一个支持缓存功能的方法。与Cacheable不同之处在于CachePut注解用来标识一个支持缓存功能的方法。它不会在执行之前检查缓存条目而是每次都执行该方法并将执行结果以键值对的形式存入指定的缓存中。
使用案例
CachePut可以用于类和方法级别的标注。使用CachePut时我们可以像Cacheable一样指定属性。
CachePut(value users) // 每次都会执行方法并将结果存入指定的缓存中
public User find(Integer id) {return null;
}CacheEvict
allEntries属性
allEntries是一个布尔类型的属性表示是否需要清除缓存中的所有元素。默认值为false表示不需要清除所有元素。当将allEntries设置为true时Spring Cache将忽略指定的key。有时我们可以通过清除所有元素来提高效率而不是逐个清除各个元素。
CacheEvict(value users, allEntries true)
public void delete(Integer id) {System.out.println(delete user by id: id);
}beforeInvocation属性
清除操作默认是在对应方法成功执行之后触发的即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation属性可以改变触发清除操作的时间当将该属性值设置为true时Spring会在调用该方法之前清除缓存中的指定元素。
CacheEvict(value users, beforeInvocation true)
public void delete(Integer id) {System.out.println(delete user by id: id);
}实际上在使用Ehcache作为实现时除了使用CacheEvict来清除缓存元素之外我们也可以通过配置Ehcache自身的驱除策略来实现。这可以通过Ehcache的配置文件来指定。
Caching
Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。它拥有三个属性cacheable、put和evict分别用于指定Cacheable、CachePut和CacheEvict。
Caching定义如下
public interface Caching { Cacheable[] cacheable() default {}; //声明多个Cacheable CachePut[] put() default {}; //声明多个CachePut CacheEvict[] evict() default {}; //声明多个CacheEvict
} 使用案例
Caching(cacheable Cacheable(users), evict {CacheEvict(cache2),CacheEvict(value cache3, allEntries true)
})
public User find(Integer id) {return null;
}自定义缓存注解
上面介绍的Caching组合会让方法上的注解显得整个代码比较乱此时可以使用自定义注解把这些注解组合到一个注解中。
Caching( put { CachePut(value user, key #user.id), CachePut(value user, key #user.username), CachePut(value user, key #user.email) }
)
Target({ElementType.METHOD, ElementType.TYPE})
Retention(RetentionPolicy.RUNTIME)
Inherited
public interface WrapperCache {
}
WrapperCache
public User save(User user) Spring允许我们在配置可缓存的方法时使用自定义的注解前提是自定义的注解上必须使用对应的注解进行标注。例如我们可以创建一个使用Cacheable进行标注的自定义注解如下所示
Target({ElementType.TYPE, ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
Cacheable(value users)
public interface MyCacheable {}然后我们可以在需要缓存的方法上使用MyCacheable进行标注以实现相同的效果。以下是优化后的示例代码
MyCacheable
public User findById(Integer id) {System.out.println(find user by id: id);User user new User();user.setId(id);user.setName(Name id);return user;
}通过这样的设置方法findById将会被缓存起来以便在后续调用中直接返回缓存的结果。如果您还有其他问题或需要进一步帮助请随时告诉我。