Spring boot 2.0的Redis缓存应用

时间:2024-11-11 14:51:01

范培忠 2018-04-18

Spring Boot2.0.在2018年3月1日正式发布。2.0下对Redis的使用与之前略有不同。具体实现如下:

        一、Maven依赖和配置

        添加3个依赖:

<dependency>
    <groupId></groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--spring2.0集成redis所需common-pool2-->
<dependency>
    <groupId></groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.5.0</version>
</dependency>
<!-- 将作为Redis对象序列化器 -->
<dependency>
    <groupId></groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>
</dependency>

        配置:

spring:
    redis:
      #数据库索引
      database: 0
      host: 127.0.0.1
      port: 6379
      password: 123
      lettuce:
        pool:
          #最大连接数
          max-active: 8
          #最大阻塞等待时间(负数表示没限制)
          max-wait: -1
          #最大空闲
          max-idle: 8
          #最小空闲
          min-idle: 0
      #连接超时时间
      timeout: 10000

        配置:

        本配置是为了解决在1.2.24后因修复漏洞导致的autotype is not support错误。

        具体解决办法为声明文件,将需要打包的类设置白名单等,如下代码所示。

        可参考官方通告:/alibaba/fastjson/wiki/enable_autotype

=.

        二、自定义序列化器

        若要实现对象的缓存,最好定义自己的序列化和反序列化器。使用阿里的fastjson来实现的比较多。

package .;

import ;
import ;
import ;
import ;

import ;

public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
    private static final Charset DEFAULT_CHARSET = ("UTF-8");
    private Class<T> clazz;

    public FastJsonRedisSerializer(Class<T> clazz) {
        super();
         = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (null == t) {
            return new byte[0];
        }
        return (t, ).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (null == bytes ||  <= 0) {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);
        return (T) (str, clazz);
    }
}

        三、添加RedisConfig配置

        在RedisConfig类里定义RedisTemplate的bean和Redis的CacheManager。

package .;

import .;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

@EnableCaching
@Configuration
@ConditionalOnClass()
@EnableConfigurationProperties()
public class RedisConfig extends CachingConfigurerSupport {

    @Bean(name = "redisTemplate")
    @SuppressWarnings("unchecked")
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();

        //使用fastjson序列化
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer();
        // value值的序列化采用fastJsonRedisSerializer
        (fastJsonRedisSerializer);
        (fastJsonRedisSerializer);
        // key的序列化采用StringRedisSerializer
        (new StringRedisSerializer());
        (new StringRedisSerializer());

        (redisConnectionFactory);
        return template;
    }

    /*@Bean
    @ConditionalOnMissingBean()
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        (redisConnectionFactory);
        return template;
    }*/

    //缓存管理器
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
         builder = RedisCacheManager
                .RedisCacheManagerBuilder
                .fromConnectionFactory(redisConnectionFactory);
        return ();
    }

}

        四、定义用于测试的User类和UserService

        User类:

package .;

import ;

public class User implements Serializable {

    private static final long serialVersionUID = -1L;

    private String username;
    private Integer age;

    public User(String username, Integer age) {
         = username;
         = age;
    }

    //getter和setter省略

}

        UserService:

package .;

import .;
import .;
import ;
import ;

@Service
public class UserServiceImpl implements UserService {
    @Override
    @Cacheable(value = "user", key = "'user_'+#username")
    public User getUser(String username) {
        (username + "进入实现类获取数据!");
        return new User("Ttomm", 22);
    }
}

        五、编写测试类

package .springbootdemoredis3;

import .;
import .;
import ;
import ;
import ;
import ;
import ;
import ;
import .;

@SuppressWarnings("unchecked")
@RunWith()
@SpringBootTest
public class SpringBootDemoRedis3ApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserService userService;

    @Test
    //直接使用redisTemplate存取字符串
    public void setAndGet() {
        ().set("test:set", "testValue1");
        ("testValue1", ().get("test:set"));
    }

    @Test
    //直接使用redisTemplate存取对象
    public void setAndGetAUser() {
        User user = new User("Tom", 10);
        ().set("test:setUser", user);
        ((), ((User) ().get("test:setUser")).getUsername());
    }

    @Test
    //使用Redis缓存对象,getUser只会被调用一次
    public void testCache() {
        User user;
        user = ("Ttomm");
        user = ("Ttomm");
        user = ("Ttomm");
    }
}

        六、执行效果

        testCache()的执行效果如下,可见后台日志显示方法仅被实际调用了一次,缓存成功: