Blame view

src/main/java/com/huaheng/framework/config/RedisConfig.java 8.61 KB
易文鹏 authored
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.huaheng.framework.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaheng.framework.redis.serializer.SerializeUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
易文鹏 authored
19
import org.springframework.data.redis.connection.RedisConnectionFactory;
易文鹏 authored
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;

@Configuration
@EnableCaching // 开启缓存支持
易文鹏 authored
36
public class RedisConfig extends CachingConfigurerSupport {
易文鹏 authored
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    @Value("${redis.database}")
    private int database;

    @Value("${redis.host}")
    private String host;

    @Value("${redis.port}")
    private int port;

    @Value("${redis.password}")
    private String password;

    @Value("${redis.ssl}")
    private Boolean ssl;

    @Value("${redis.lettuce.pool.max-idle}")
    private int maxIdle;

    @Value("${redis.lettuce.pool.min-idle}")
    private int minIdle;

    @Value("${redis.lettuce.pool.max-total}")
    private int maxTotal;

    @Value("${redis.lettuce.pool.max-waitMillis}")
    private long maxWaitMillis;

    @Value("${redis.timeout}")
    private long timeout;

    private Duration timeToLive = Duration.ofSeconds(600);

    /**
     * 在没有指定缓存Key的情况下,key生成策略
     */
    @Bean
易文鹏 authored
73
74
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
易文鹏 authored
75
            @Override
易文鹏 authored
76
            public Object generate(Object target, Method method, Object... params) {
易文鹏 authored
77
78
79
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
易文鹏 authored
80
                for (Object obj : params) {
易文鹏 authored
81
82
83
84
85
86
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }
易文鹏 authored
87
易文鹏 authored
88
89
90

    // 缓存管理器 使用Lettuce,和jedis有很大不同LettuceConnectionFactory lettuceConnectionFactory
    @Bean
易文鹏 authored
91
    public CacheManager cacheManager() {
易文鹏 authored
92
93
94
95
96
        // 关键点,spring cache的注解使用的序列化都从这来,没有这个配置的话使用的jdk自己的序列化,实际上不影响使用,只是打印出来不适合人眼识别
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))// key序列化方式
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(getValueSerializer()))// value序列化方式
                .disableCachingNullValues().entryTtl(timeToLive).disableCachingNullValues();
易文鹏 authored
97
        // 缓存过期时间
易文鹏 authored
98
99
100
101
102
103
104
105
106
107
108

        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder
                .fromConnectionFactory(lettuceConnectionFactory())// 默认有锁 等待锁时间为0
                .cacheDefaults(redisCacheConfiguration).transactionAware();
        return builder.build();
    }

    /**
     * RedisTemplate配置 使用自定义redisTemplate的时候 重新定义序列化方式 LettuceConnectionFactory lettuceConnectionFactory
     */
    @Bean
易文鹏 authored
109
    public RedisTemplate<String, Object> redisTemplate() {
易文鹏 authored
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory());

        RedisSerializer<?> stringSerializer = new StringRedisSerializer();

        redisTemplate.setKeySerializer(stringSerializer);// key序列化
        redisTemplate.setValueSerializer(getValueSerializer());// value序列化new LZ4Serializer(getValueSerializer())
        redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        redisTemplate.setHashValueSerializer(getValueSerializer());// Hash value序列化
        redisTemplate.afterPropertiesSet();

        return redisTemplate;
    }

    /**
     * shiroRedisTemplate配置 使用自定义shiroRedisTemplate的时候 重新定义序列化方式 LettuceConnectionFactory lettuceConnectionFactory
     */
    @Bean
易文鹏 authored
129
    public RedisTemplate<String, Object> shiroRedisTemplate() {
易文鹏 authored
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
        // 配置redisTemplate
        RedisTemplate<String, Object> shiroRedisTemplate = new RedisTemplate<String, Object>();
        shiroRedisTemplate.setConnectionFactory(lettuceConnectionFactory());

        RedisSerializer<?> stringSerializer = new StringRedisSerializer();

        shiroRedisTemplate.setKeySerializer(stringSerializer);// key序列化
        shiroRedisTemplate.setValueSerializer(new SerializeUtils<Object>());// value序列化
        shiroRedisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        shiroRedisTemplate.setHashValueSerializer(new SerializeUtils<Object>());// Hash value序列化
        shiroRedisTemplate.afterPropertiesSet();

        return shiroRedisTemplate;
    }
易文鹏 authored
145
    private RedisSerializer<String> keySerializer() {
易文鹏 authored
146
147
148
        return new StringRedisSerializer();
    }
易文鹏 authored
149
    private RedisSerializer<Object> getValueSerializer() {
易文鹏 authored
150
        // 设置序列化
易文鹏 authored
151
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
易文鹏 authored
152
153
154
155
156
157
158
159
160
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        return jackson2JsonRedisSerializer;
    }

    // 单机版配置连接参数
    @Bean
易文鹏 authored
161
    public RedisStandaloneConfiguration redisStandaloneConfiguration() {
易文鹏 authored
162
163
164
165
166
167
168
169
170
171
172
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
        redisStandaloneConfiguration.setDatabase(database);
        redisStandaloneConfiguration.setHostName(host);
        redisStandaloneConfiguration.setPort(port);
        redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
        return redisStandaloneConfiguration;
    }

    /**
     * 配置LettuceClientConfiguration 包括线程池配置和安全项配置 genericObjectPoolConfig common-pool2线程池GenericObjectPoolConfig
     * genericObjectPoolConfig
易文鹏 authored
173
     *
易文鹏 authored
174
175
176
     * @return lettuceClientConfiguration
     */
    @Bean
易文鹏 authored
177
    public LettuceClientConfiguration lettuceClientConfiguration() {
易文鹏 authored
178
179
180
        LettuceClientConfiguration lettuceClientConfiguration = LettucePoolingClientConfiguration.builder()
                .commandTimeout(Duration.ofMillis(timeout)).shutdownTimeout(Duration.ofMillis(200))
                .poolConfig(genericObjectPoolConfig()).build();
易文鹏 authored
181
        if (ssl) {
易文鹏 authored
182
183
184
185
186
187
188
            lettuceClientConfiguration.isUseSsl();
        }
        return lettuceClientConfiguration;
    }

    // 设置连接工厂
    @Bean
易文鹏 authored
189
    public LettuceConnectionFactory lettuceConnectionFactory() {
易文鹏 authored
190
191
192
193
194
195
196
197
198
199
        return new LettuceConnectionFactory(redisStandaloneConfiguration(), lettuceClientConfiguration());
    }

    /**
     * GenericObjectPoolConfig 连接池配置
     */
    @Bean
    @ConfigurationProperties(prefix = "redis.lettuce.pool")
    @Scope(value = "prototype")
    @SuppressWarnings("rawtypes")
易文鹏 authored
200
    public GenericObjectPoolConfig genericObjectPoolConfig() {
易文鹏 authored
201
202
203
        return new GenericObjectPoolConfig();
    }
}