转载

在 spring boot 中使用spring cache + redis

参考文档:

a. 官方文档:

https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache

b.其他文档

http://www.cnblogs.com/x113773/p/7227114.html

注释驱动的 spring cache

https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/

1. 在 build.gradle 中配置 spring cache的支持和 reids 支持

// 使用 spring cache
compile("org.springframework.boot:spring-boot-starter-cache")
// ---------------------------------------
compile('org.springframework.boot:spring-boot-starter-data-redis')

2.在 applicaiton.yaml 中配置 redis

srping:
    redis:
        #host: 120.76.101.180
        host: 127.0.0.1
        password: xxxxxxxxx
        port: 16379
        database: 2
        ## 连接超时时间(毫秒)
        timeout: 0
        pool:
            ## 连接池最大连接数(使用负值表示没有限制)
            max-active: 8
            ## 连接池最大阻塞等待时间(使用负值表示没有限制)
            max-wait: -1
            ## 连接池中的最大空闲连接
            max-idle: 8
            ## 连接池中的最小空闲连接
            min-idle: 0

3.在项目的主程序中,引入 spring cache

@EnableCaching
@Log4j2
public class RilApplication  extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(RilApplication.class, args);
    }

}

4.在项目的 service 中使用缓存

@Log4j2
@Data
@Service("com.alcor.ril.service.UserService")
@CacheConfig(cacheNames = "UserEntity")
public class UserService {
    @Qualifier("com.alcor.ril.repository.IUserRepository")
    @Autowired
    IUserRepository iUserRepository;
    
    @Cacheable()  //等价于@Cacheable(key = "#name")
    public UserEntity findByName(String name) {
        log.debug("cache 没有命中,进行数据库查询!");
        return iUserRepository.findOne(name);
    }
    
    @CachePut(key = "#userEntity.name")
    public UserEntity update(UserEntity userEntity) throws ServiceException {
        return iUserRepository.save(userEntity);
    }
    ....    
}

5.注解的使用

在 spring boot 中使用spring cache + redis

6.注意点:

a. 放入缓存的对象,比如 EntityBean,必须 implements Serializable

b. @Cacheable() 的使用

@Cacheable() 是先在缓存中查找,如果没有就执行方法里面的代码,如果找到了,就直接返回 cache 里面的对象

1) 其中value 参数是一个字符串,代表在 redis 里面会建立以这个字符串命名的 set 对象。在srping cache 1.4以后,多了一个 cacheNames ,其实就是 value 的别名。二者等价,建议使用 cacheName。如果不设置,spring 会去类上找 @CacheConfig中指定的 cacheNames.

2) set 值是保存的 cache 中 set 的 key 值,如果不指定,则spring 会把方法所有的参数整理放入。也可以设置为通过 SpEL 指定的返回值。

例如:

  • 在这个例子里面:

@Cacheable() //等价于@Cacheable(key = "#name")

public UserEntity findByName(String name) {...}

表示 会把参数 name的值当做 redis 中的 set 的 key 值。代表着如果 name 是“张三”的话,就会产生 set 值是"张三"的一个 UserEntity 的对象(序列化后的)。
  • 在这个例子里面:

@CachePut(key = "#userEntity.name")

public UserEntity update(UserEntity userEntity) throws ServiceException {

return iUserRepository.save(userEntity);

}

表示会把 参数 userEntity 对象实例中的name 属性值的内容作为 redis 的 set 中的 key 值,然后对这个 key对应的内容进行更新。

3) cache 放置,或者更新的值,就是函数返回的对象序列化后的内容。

7.填坑

a. 为了更有效的对cache 进行管理。尝试把 service 上的注解移到 repository interface 上。

package com.alcor.ril.repository;

import com.alcor.ril.entity.UserEntity;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

@Repository("com.alcor.ril.repository.IUserRepository")
@CacheConfig(cacheNames = "spring:cache:UserEntity")
public interface IUserRepository extends JpaRepository<UserEntity, String>, PagingAndSortingRepository<UserEntity, String> {

    @Cacheable()
    public UserEntity findOne(String name);

    @CachePut(key = "#p0.name")
    public UserEntity save(UserEntity userEntity);
}

这样 service 中只要调用 repository 中的 findXXX 方法,就会进行缓存管理。调用 update 方法,就会进行缓存更新。

这个时候,如果沿用 service 上使用 #name 作为的写法,就会产生:

Null key returned for cache operation (maybe you are using named params on classes without debug info?


这样的错误。

解决方案:

见上面的代码,使用#p0这样的写法。

具体的解析看下面的博文:

http://www.jianshu.com/p/6196dd5870c7
原文  http://blog.csdn.net/remote_roamer/article/details/78628545
正文到此结束
Loading...