springboot增加注解缓存@Cacheable的实现

网友投稿 227 2022-09-07


springboot增加注解缓存@Cacheable的实现

目录springboot增加注解缓存@Cacheable业务层使用配置@Cacheable注解的属性使用cacheNames和valuekeykeyGeneratorkeyGeneratorconditionunless(除非)sync

springboot增加注解缓存@Cacheable

业务层使用

@Cacheable(value = "dictionary#1800", key = "#root.targetClass.simpleName +':'+ #root.methodName +':'+ #code")

public Object findByCode(String code) {

//业务

}

配置

import org.springframework.cache.Cache;

import org.springframework.data.redis.cache.RedisCache;

import org.springframework.data.redis.cache.RedisCacheManager;

import org.springframework.data.redis.core.RedisOperations;

import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ConcurrentMap;

public clanrtAAeTZblss MyRedisCacheManager extends RedisCacheManager {

/**

* 过期时间分隔符

*/

private static final String TTLSEPARATOR = "#";

private final ConcurrentMap cacheMap = new ConcurrentHashMap(16);

/**

* 过期时间, 单位为 秒

*/

private long defaultExpiration = 0;

public MyRedisCacheManager(RedisOperations redisOperations) {

super(redisOperations);

}

@Override

public Cache getCache(String name) {

long expiredTime = defaultExpiration;

if (name.contains(TTLSEPARATOR)) {

String[] split = name.split(TTLSEPARATOR);

String cacheName = split[0];

try {

expiredTime = Double.valueOf(split[1]).longValue();

} catch (Exception e) {

nrtAAeTZbl e.printStackTrace();

}

Cache cache = this.cacheMap.get(name);

if (cache != null) {

return cache;

} else {

synchronized (this.cacheMap) {

cache = this.cacheMap.get(name);

if (cache == null) {

cache = new RedisCache(cacheName, null, super.getRedisOperations(), expiredTime);

if (cache != null) {

cache = this.decorateCache(cache);

this.cacheMap.put(name, cache);

}

}

return cache;

}

}

}

return super.getCache(name);

}

}

import com.fasterxml.jackson.annotation.jsonTypeInfo;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.cache.CacheManager;

import org.springframework.cache.annotation.CacheConfig;

import org.springframework.cache.annotation.CachingConfigurerSupport;

import org.springframework.cache.annotation.EnableCaching;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;

@CacheConfig

@Configuration

@EnableCaching

public class RedisConfig extends CachingConfigurerSupport {

@Bean

public CacheManager cacheManager(RedisTemplate redisTemplate) {

//设置序列化Key的实例化对象

redisTemplate.setKeySerializer(new StringRedisSerializer());

//设置序列化Value的实例化对象

ObjectMapper mapper = new ObjectMapper();

mapper.findAndRegisterModules();

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer(mapper);

redisTemplate.setValueSerializer(serializer);

MyRedisCacheManager mrc = new MyRedisCacheManager(redisTemplate);

return mrc;

}

}

@Cacheable注解的属性使用

cacheNames和value

指定缓存组件的名字,通过下面代码可以看出可以将返回结果放在哪个缓存中,可以通过数组的方式指定多个缓存

/**

* Alias for {@link #cacheNames}.

*/

@AliasFor("cacheNames")

String[] value() default {};

/**

* Names of the caches in which method invocation results are stored.

*

Names may be used to determine the target cache (or caches), matching

* the qualifier value or bean name of a specific bean definition.

* @since 4.2

* @see #value

* @see CacheConfig#cacheNames

*/

@AliasFor("value")

String[] cacheNames() default {};

key

缓存数据的时候使用的key,它是用来指定对应的缓存,模拟使用方法参数值作为key的值。也可以使用SpEL表达式的值来指定

/**

* Spring Expression LangunrtAAeTZblage (SpEL) expression for computing the key dynamically.

*

Default is {@code ""}, meaning all method parameters are considered as a key,

* unless a custom {@link #keyGenerator} has been configured.

*

The SpEL expression evaluates against a dedicated context that provides the

* following meta-data:

*

*

* references to the {@link java.lang.reflect.Method method}, target object, and

* affected cache(s) respectively.

*

* ({@code #root.targetClass}) are also available.

*

* can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments

* can also be accessed by name if that information is available.

*

*/

String key() default "";

名称

位置

描述

示例

methodName

root object

被调用的方法名称

#root.methodName

Method

root object

被调用的方法

#root.method.name

Target

root object

当前被调用的目标对象

#root.target

targetClass

root object

当前被调用的目标对象类

#root.targetClass

args

root object

被调用方法的参数列表#root.args[0]

caches

root object

调用的缓存列表

#root.caches[0].name

argument name

evaluation context

方法的参数名称可以直接使用#参数名

#p0,#a0等等

result

evaluation context

执行方法后的返回值

#result

可以通过这个参数提示列表看看到这个key所支持的root object对象有哪些,通过这样的方式可以指定对应的key值。

keyGenerator

这个是表示指定的key的生成器,当然在之前分享中我们说过一个简单的key的生成策略。这里我们还可以通过自定的方式来实现这个key的生成策略。

keyGenerator

这个是表示指定的key的生成器,当然在之前分享中我们说过一个简单的key的生成策略。这里我们还可以通过自定的方式来实现这个key的生成策略。

import org.springframework.cache.interceptor.KeyGenerator;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import java.lang.reflect.Method;

import java.util.Arrays;

@Configuration

public class MyCacheConfig {

@Bean("myKeyGenerator")

public KeyGenerator keyGenerator(){

return new KeyGenerator() {

@Override

public Object generate(Object target, Method method, Object... params) {

return method.getName()+"["+ Arrays.asList(params).toString()+"]";

}

};

}

}

在使用的时候可以通过一下的方式进行配置

@Cacheable(cacheNames = {"emp"},keyGenerator = "myKeyGenerator")

cacheManager指定缓存管理器

/**

* The bean name of the custom {@link org.springframework.cache.CacheManager} to use to

* create a default {@link org.springframework.cache.interceptor.CacheResolver} if none

* is set already.

*

Mutually exclusive with the {@link #cacheResolver} attribute.

* @see org.springframework.cache.interceptor.SimpleCacheResolver

* @see CacheConfig#cacheManager

*/

String cacheManager() default "";

/**

* The bean name of the custom {@link org.springframework.cache.interceptor.CacheResolver}

* to use.

* @see CacheConfig#cacheResolver

*/

String cacheResolver() default "";

condition

指定复合条件的情况下才缓存。也可以通过SpEL表达式进行设置。这个配置规则和上面表格中的配置规则是相同的。

/**

* Spring Expression Language (SpEL) expression used for making the method

* caching conditional.

*

Default is {@code ""}, meaning the method result is always cached.

*

The SpEL expression evaluates against a dedicated context that provides the

* following meta-data:

*

*

* references to the {@link java.lang.reflect.Method method}, target object, and

* affected cache(s) respectively.

*

* ({@code #root.targetClass}) are also available.

*

* can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments

* can also be accessed by name if that information is available.

*

*/

String condition() default "";

unless(除非)

当这个条件为true的时候,方法的返回值就不会被缓存。

/**

* Spring Expression Language (SpEL) expression used to veto method caching.

*

Unlike {@link #condition}, this expression is evaluated after the method

* has been called and can therefore refer to the {@code result}.

*

Default is {@code ""}, meaning that caching is never vetoed.

*

The SpEL expression evaluates against a dedicated context that provides the

* following meta-data:

*

*

* supported wrappers such as {@code Optional}, {@code #result} refers to the actual

* object, not the wrapper

*

* references to the {@link java.lang.reflect.Method method}, target object, and

* affected cache(s) respectively.

*

* ({@code #root.targetClass}) are also available.

*

* can be accessed via {@code #root.args[1]}, {@code #p1} or {@code #a1}. Arguments

* can also be accessed by name if that information is available.

*

* @since 3.2

*/

String unless() default "";

sync

是否异步

/**

* Synchronize the invocation of the underlying method if several threads are

* attempting to load a value for the same key. The synchronization leads to

* a couple of limitations:

*

*

*

*

*

* This is effectively a hint and the actual cache provider that you are

* using may not support it in a synchronized fashion. Check your provider

* documentation for more details on the actual semantics.

* @since 4.3

* @see org.springframework.cache.Cache#get(Object, Callable)

*/

boolean sync() default false;

注意

在使用这个属性的时候,当这个属性为true的时候,unless属性是不能使用的。

{@link #unless()} is not supported


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:【图像隐藏】基于LDPC编码译码结合DCT算法实现图像水印嵌入提取含Matlab源码
下一篇:Python与金融:为什么将Python用于金融(python对金融的作用)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~