springboot2整合redis,並自定義@Cache
阿新 • • 發佈:2018-11-03
1.maven依賴
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!-- springboot2.x預設使用lettuce 不是jedis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.0</version> </dependency>
2.application.properties配置
#資料庫索引 預設值0 spring.redis.database=0 spring.redis.host=182.92.234.232 spring.redis.port=6379 spring.redis.password= #連線池最大連線數 負值表示無限制 spring.redis.jedis.pool.max-active=8 #連線池最大阻塞等待時間 負值表示無限制 spring.redis.jedis.pool.max-wait=-1 #連線池最大空閒連線 spring.redis.jedis.pool.max-idle=8 #連線池最小空閒連線 spring.redis.jedis.pool.min-idle=0 #連線超時時間(單位為毫秒) spring.redis.timeout=2000
3.自定義RedisConfig
@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, Visibility.ANY); objectMapper.enableDefaultTyping(DefaultTyping.NON_FINAL); Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class); jsonRedisSerializer.setObjectMapper(objectMapper); redisTemplate.setDefaultSerializer(jsonRedisSerializer); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } }
4.自定義快取Service (key:string value:object)
public interface IRedisCacheService {
/**
* @param expire TimeUnit.SECONDS
*/
void setCache(String key, Object value, int expire);
Object getCache(String key);
void clearCache(String key);
}
@Service
public class RedisCacheServiceImpl implements IRedisCacheService {
private static final Logger logger = LoggerFactory.getLogger(RedisCacheServiceImpl.class);
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Override
public void setCache(String key, Object value, int expire) {
redisTemplate.opsForValue().set(key, value);
redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
@Override
public Object getCache(String key) {
return redisTemplate.opsForValue().get(key);
}
@Override
public void clearCache(String key) {
redisTemplate.delete(key);
}
}
5.測試Service
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
@Autowired
private IRedisCacheService redisCacheServiceImpl;
@Autowired
private IUserService userServiceImpl;
@Test
public void add() {
User user = new User("tom", "123456");
redisCacheServiceImpl.setCache("redisKey", user, 200);
}
@Test
public void get() {
User user = (User) redisCacheServiceImpl.getCache("redisKey");
System.out.println(user);
}
@Test
public void delete() {
redisCacheServiceImpl.clearCache("redisKey");
}
}
6.自定義註解Cache
@Inherited
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache {
/**
* 字首 後面會拼引數
*/
String prefix() default "";
/**
* 快取失效時間5分鐘
*/
int expiredTime() default 60 * 5;
}
7.對@Cache的切面
@Aspect
@Service
public class CacheAspect {
private static final Logger logger = LoggerFactory.getLogger(CacheAspect.class);
private static final String el = "@annotation(com.boomsecret.annotation.Cache)";
private static final String SYMBOL = ".";
@Autowired
private IRedisCacheService redisCacheServiceImpl;
@Around(el)
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = methodSignature.getMethod();
Cache cache = method.getAnnotation(Cache.class);
StringBuilder sb = new StringBuilder();
sb.append(methodSignature.getReturnType().getName()).append(SYMBOL)
.append(method.getName()).append(SYMBOL)
.append(cache.prefix()).append(SYMBOL);
Object[] args = proceedingJoinPoint.getArgs();
if(args.length > 0){
for(Object arg : args){
if(arg != null){
sb.append(arg.toString()).append(SYMBOL);
}
}
}
String redisKey = sb.substring(0, sb.length() - 1);
Object redisCacheResult = null;
try {
redisCacheResult = redisCacheServiceImpl.getCache(redisKey);
} catch (Exception e) {
logger.warn("obtain value from redis error. key : " + redisKey);
}
if(redisCacheResult != null){
return redisCacheResult;
}
redisCacheResult = proceedingJoinPoint.proceed();
if(redisCacheResult != null){
try {
redisCacheServiceImpl.setCache(redisKey, redisCacheResult, cache.expiredTime());
} catch (Exception e) {
logger.warn("set value to redis error. key: " + redisKey);
}
}
return redisCacheResult;
}
}
@Cache(prefix = "key", expiredTime = 200)
@Override
public User getUser() {
return new User(UUID.randomUUID().toString(), "123456");
}
@Test
public void testCacheAnnotation() {
// 2次取出相同
User temp001 = userServiceImpl.getUser();
User temp002 = userServiceImpl.getUser();
System.out.println(temp001);
System.out.println(temp002);
}
原始碼 https://gitee.com/jsjack_wang/springboot-demo dev-redis分支