項目github地址:https://github.com/5-Ason/aso...
具體可看 ./db/db-redis 和 ./db/db-cache 兩個模塊java
// TODO 在整合redis以前須要先本地配置好redis環境,遲點有時間補一下linux下下載安裝配置redis
本文主要實現的是對數據操做進行獨立模塊得整合,詳情請看個人另外一篇博文:
【技術雜談】springcloud微服務之數據操做獨立模塊化linux
獨立部署Redis非關係型數據庫做爲內存緩存模塊,實現SpringBoot項目中依賴緩存模塊進行緩存操做,並進行簡單測試。git
<!-- Spring Boot Redis 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- Spring Boot Cache 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
由於個人項目使用的是springcloud分佈式配置
因此配置文件在 ./config-server/config-repo/data-dev.yml,具體配置以下:github
# ====================redis==================== redis: # Redis服務器地址 host: ason-hostname # Redis服務器鏈接端口 port: 6379 # Redis服務器鏈接密碼(默認爲空) password: # 鏈接超時時間(毫秒) timeout: 0 # Redis數據庫索引(默認爲0) database: 0 pool: # 鏈接池最大鏈接數(使用負值表示沒有限制) max-active: 8 # 鏈接池最大阻塞等待時間(使用負值表示沒有限制) max-wait: -1 # 鏈接池中的最大空閒鏈接 max-idle: 8 # 鏈接池中的最小空閒鏈接 min-idle: 0
package com.ason; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; /** * Created by Ason on 2017-09-23. */ @Configuration public class RedisConf { private static final Log log = LogFactory.getLog(RedisConf.class); @Value("${redis.host}") private String host; // Redis服務器地址 @Value("${redis.port}") private int port; // Redis服務器鏈接端口 @Value("${redis.password}") private String password; // Redis服務器鏈接密碼(默認爲空) @Value("${redis.timeout}") private int timeout; // 鏈接超時時間(毫秒) @Value("${redis.database}") private int database; // 鏈接超時時間(毫秒) @Value("${redis.pool.max-active}") private int maxTotal; // 鏈接池最大鏈接數(使用負值表示沒有限制) @Value("${redis.pool.max-wait}") private int maxWaitMillis; // 鏈接池最大阻塞等待時間(使用負值表示沒有限制) @Value("${redis.pool.max-idle}") private int maxIdle; // 鏈接池中的最大空閒鏈接 @Value("${redis.pool.min-idle}") private int minIdle; // 鏈接池中的最小空閒鏈接 /** * 配置JedisPoolConfig * @return JedisPoolConfig實體 */ @Bean(name = "jedisPoolConfig") public JedisPoolConfig jedisPoolConfig() { log.info("初始化JedisPoolConfig"); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxTotal(this.maxTotal); // 鏈接池最大鏈接數(使用負值表示沒有限制) jedisPoolConfig.setMaxWaitMillis(this.maxWaitMillis); // 鏈接池最大阻塞等待時間(使用負值表示沒有限制) jedisPoolConfig.setMaxIdle(this.maxIdle); // 鏈接池中的最大空閒鏈接 jedisPoolConfig.setMinIdle(this.minIdle); // 鏈接池中的最小空閒鏈接 // jedisPoolConfig.setTestOnBorrow(true); // jedisPoolConfig.setTestOnCreate(true); // jedisPoolConfig.setTestWhileIdle(true); return jedisPoolConfig; } /** * 實例化 RedisConnectionFactory 對象 * @param poolConfig * @return */ @Bean(name = "jedisConnectionFactory") public RedisConnectionFactory jedisConnectionFactory(@Qualifier(value = "jedisPoolConfig") JedisPoolConfig poolConfig) { log.info("初始化RedisConnectionFactory"); JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig); jedisConnectionFactory.setHostName(this.host); jedisConnectionFactory.setPort(this.port); jedisConnectionFactory.setDatabase(this.database); return jedisConnectionFactory; } /** * 實例化 RedisTemplate 對象 * @return */ @Bean(name = "redisTemplate") public RedisTemplate<String, String> functionDomainRedisTemplate(@Qualifier(value = "jedisConnectionFactory") RedisConnectionFactory factory) { log.info("初始化RedisTemplate"); RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new EntityRedisSerializer()); redisTemplate.setValueSerializer(new EntityRedisSerializer()); redisTemplate.afterPropertiesSet(); redisTemplate.setEnableTransactionSupport(true); return redisTemplate; } }
package com.ason; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.SerializationException; /** * 自定義Redis序列化 * Created by Ason on 2017-09-23. */ public class EntityRedisSerializer implements RedisSerializer<Object> { @Override public byte[] serialize(Object t) throws SerializationException { if (t == null) { return new byte[0]; } return SerializeUtil.serialize(t); } @Override public Object deserialize(byte[] bytes) throws SerializationException { if (bytes == null || bytes.length == 0) { return null; } return SerializeUtil.unserialize(bytes); } }
package com.ason; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; /** * 定義序列化 * Created by Ason on 2017-09-23. */ public class SerializeUtil { public static byte[] serialize(Object object) { ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(object); byte[] bytes = baos.toByteArray(); return bytes; } catch (Exception e) { e.printStackTrace(); } return null; } public static Object unserialize(byte[] bytes) { ByteArrayInputStream bais = null; try { // 反序列化 bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); } return null; } }
package com.ason; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; 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.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.core.RedisTemplate; import java.lang.reflect.Method; /** * Created by Ason on 2017/9/25. * 這裏實現CachingConfigurerSupport主要是方便使用自定義keyGenerator */ @Configuration @EnableCaching // 啓用緩存 public class RedisCacheConf extends CachingConfigurerSupport { @Autowired private RedisTemplate redisTemplate; private static final Log log = LogFactory.getLog(RedisConf.class); /** * 配置redis緩存管理對象 * @return */ @Bean(name = "cacheManager") public CacheManager cacheManager() { log.info("初始化CacheManager"); RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); // Map<String, Long> expires = new HashMap<>(); // expires.put("cache:user", 36000L); // cacheManager.setExpires(expires); //設置緩存過時時間 //cacheManager.setDefaultExpiration(10000); return cacheManager; } /** * 生成key的策略 * 此方法將會根據類名+方法名+全部參數的值生成惟一的一個key,即便@Cacheable中的value屬性同樣,key也會不同。 * @return */ @Bean public KeyGenerator keyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } }
由於是將redis的配置單獨做爲一個模塊db-redis,CacheManager的配置模塊db-cache依賴db-redis:redis
<dependency> <groupId>com.ason</groupId> <artifactId>db-redis</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
因此個人rms-service微服務想進行緩存的操做,需依賴db-cache模塊:spring
<dependency> <groupId>com.ason</groupId> <artifactId>db-cache</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
同時,還須要讀取redis配置的屬性,上面個人配置是放在 ./config-server/config-repo/data-dev.yml 下,因此在rms-service微服務下的 bootstrap.yml 配置文件中,須要指定配置中心服務的地址以及配置文件的name和profile:數據庫
spring: # 配置中心服務的地址 cloud: config: name: data profile: ${spring.profiles.active} # 要讀取的配置文件profile屬性 # uri: http://127.0.0.1:7001 #label: ${spring.profiles.active} discovery: enabled: true # 默認false,設爲true表示使用註冊中心中的configserver配置而不本身配置configserver的uri serviceId: config-server profiles: active: dev
接下來,便可使用緩存相關的註解在 rms-service 微服務下使用緩存,在 RmsUserController(僅爲測試,實際開發中根據需求作調整) 添加:apache
/** * 查詢單個用戶 */ @Cacheable(value = "usercache", key = "#account") @PostMapping(value = "/account", produces = "application/json;charset=UTF-8") public String findUserByAccout(@RequestParam("account") String account) throws Exception { return ResultBody.success(rmsUserService.selectUserByAccout(account)); }
啓動項目,post請求訪問 http://localhost:8888/rms/use...json
接下來,再去redis看一下,發現11@qq.com已做爲key保存起來了:bootstrap
有些情形下註解式緩存會不起做用的(本人第一次整合測試遇到的坑):
同一個bean內部方法調用、子類調用父類中有緩存註解的方法等。
至此,已完成 springboot 整合獨立模塊 redis 作緩存
詳情請看github地址:https://github.com/5-Ason/aso...