SpringBoot實戰之13 整合redis
工欲善其事必先利其器;預備一下工具對於整個環境的整合有極大的幫助
- redisDesktopManage redis視覺化工具安裝
- idea開發工具
開始
現如今,越來越多的公司注重使用者對網站訪問速度的體驗。而快取技術的出現無疑很好的適用以上場景。
因此掌握一門快取技術對一名IT男無疑是必要的。
建立springboot-redis專案
新增依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId >
</dependency>
<!--redis連線池-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--測試框架-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId >
</dependency>
<!--json序列化-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!--自己封裝的redis增刪改查方法-->
<dependency>
<groupId>com.hsy.java</groupId>
<artifactId >java-util</artifactId>
</dependency>
建立redis配置檔案
新建conf/redis.properties檔案
#Matser的ip地址
redis.host=172.16.191.102
#埠號
redis.port=6379
#如果有密碼
redis.password=123456
# 資料庫索引
redis.database=0
#客戶端超時時間單位是毫秒 預設是2000
redis.timeout=10000
#最大空閒數
redis.pool.maxIdle=300
#連線池的最大資料庫連線數。設為0表示無限制,如果是jedis 2.4以後用redis.maxTotal
#redis.pool.maxActive=600
#控制一個pool可分配多少個jedis例項,用來替換上面的redis.maxActive,如果是jedis 2.4以後用該屬性
redis.pool.maxTotal=1000
#最大建立連線等待時間。如果超過此時間將接到異常。設為-1表示無限制。
redis.pool.maxWaitMillis=1000
#連線的最小空閒時間 預設1800000毫秒(30分鐘)
redis.pool.minEvictableIdleTimeMillis=300000
#每次釋放連線的最大數目,預設3
redis.pool.numTestsPerEvictionRun=1024
#逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1
redis.pool.timeBetweenEvictionRunsMillis=30000
#是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個
redis.pool.testOnBorrow=true
#在空閒時檢查有效性, 預設false
redis.pool.testWhileIdle=true
新建RedisConfig.java
package com.hsy.springboot.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
/**
* @author heshiyuan
* @description <p></p>
* @path springboot/com.hsy.springboot.redis.config
* @date 2018/7/26 9:09
* @github http://github.com/shiyuan2he
* @email [email protected]
* Copyright (c) 2018 [email protected] All rights reserved.
* @price ¥5 微信:hewei1109
*/
@Configuration
@PropertySource("classpath:config/redis.properties")
public class RedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.port}")
private Integer port;
@Value("${redis.password}")
private String password;
@Value("${redis.database}")
private Integer database;
@Value("${redis.timeout}")
private Integer timeout;
@Value("${redis.pool.maxIdle}")
private Integer maxIdle;
@Value("${redis.pool.maxTotal}")
private Integer maxTotal;
@Value("${redis.pool.maxWaitMillis}")
private Integer maxWaitMillis;
@Value("${redis.pool.minEvictableIdleTimeMillis}")
private Integer minEvictableIdleTimeMillis;
@Value("${redis.pool.numTestsPerEvictionRun}")
private Integer numTestsPerEvictionRun;
@Value("${redis.pool.timeBetweenEvictionRunsMillis}")
private long timeBetweenEvictionRunsMillis;
@Value("${redis.pool.testOnBorrow}")
private boolean testOnBorrow;
@Value("${redis.pool.testWhileIdle}")
private boolean testWhileIdle;
/**
* JedisPoolConfig 連線池
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空閒數
jedisPoolConfig.setMaxIdle(maxIdle);
// 連線池的最大資料庫連線數
jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立連線等待時間
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出連線的最小空閒時間 預設1800000毫秒(30分鐘)
jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出檢查時 逐出的最大數目 如果為負數就是 : 1/abs(n), 預設3
jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出掃描的時間間隔(毫秒) 如果為負數,則不執行逐出執行緒, 預設-1
jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在從池中取出連線前進行檢驗,如果檢驗失敗,則從池中去除連線並嘗試取出另一個
jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空閒時檢查有效性, 預設false
jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* 單機版配置
* @Title: JedisConnectionFactory
* @param @param jedisPoolConfig
* @param @return
* @return JedisConnectionFactory
* @autor lpl
* @date 2018年2月24日
* @throws
*/
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(jedisPoolConfig);
jedisConnectionFactory.setUsePool(true);
//連線池
jedisConnectionFactory.setPoolConfig(jedisPoolConfig);
//IP地址
jedisConnectionFactory.setHostName(host);
//埠號
jedisConnectionFactory.setPort(port);
//如果Redis設定有密碼
jedisConnectionFactory.setPassword(password);
// 設定資料庫索引號
jedisConnectionFactory.setDatabase(database);
//客戶端超時時間單位是毫秒
jedisConnectionFactory.setTimeout(timeout);
return jedisConnectionFactory;
}
/**
* 例項化 RedisTemplate 物件
*
* @return
*/
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
return redisTemplate;
}
/**
* 設定資料存入 redis 的序列化方式,並開啟事務
*
* @param redisTemplate
* @param factory
*/
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
//如果不配置Serializer,那麼儲存的時候預設使用String,如果用User型別儲存,那麼會提示錯誤User can't cast to String!
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
// GenericJackson2JsonRedisSerializer序列化方式
//redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
//redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// Jackson2JsonRedisSerializer序列化方式
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//set value serializer
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
// 開啟事務
redisTemplate.setEnableTransactionSupport(true);
redisTemplate.setConnectionFactory(factory);
redisTemplate.afterPropertiesSet();
}
}
建立入口類
@SpringBootApplication
public class SpringBootRedisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootRedisApplication.class,args) ;
}
}
建立dao層資料介面檔案
RedisRepository.java
@Repository(value = "redisRepository")
public class RedisRepository extends AbstractSpringRedisCacheEnhance{
@Autowired
RedisTemplate<String, Object> redisTemplate;
@Override
public StringRedisTemplate getStringRedisTemplate() {
return null;
}
@Override
public RedisTemplate<String, Object> getRedisTemplate() {
return redisTemplate;
}
}
AbstractSpringRedisCacheEnhance封裝有crud方法,有上千行程式碼,就不貼在這裡了,
有興趣的可以去我github上fork。後面會附上原始碼地址
建立測試類
package com.hsy.springboot.redis;
import com.hsy.springboot.redis.dao.RedisRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* @author heshiyuan
* @description <p></p>
* @path spring/com.hsy.spring.redis.dao
* @date 2018/7/23 18:42
* @github http://github.com/shiyuan2he
* @email [email protected]
* Copyright (c) 2018 [email protected] All rights reserved.
* @price ¥5 微信:hewei1109
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootRedisApplication.class)
public class RedisRepositoryTest {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired private RedisRepository redisRepository;
public Map<String, Object> generateMap(){
Map<String, Object> returnMap = new HashMap<>();
returnMap.put("aa", "aa");
Map<String, Object> innerMap = new HashMap<>();
innerMap.put("ss", 3);
innerMap.put("rr",false);
innerMap.put("tt","中文");
returnMap.put("bb", innerMap);
returnMap.put("cc", 1.000);
returnMap.put("dd", true);
returnMap.put("ee", 2);
return returnMap;
}
public List<Map<String, Object>> generateList(){
List<Map<String, Object>> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(generateMap());
}
return list;
}
@Test
public void clear(){
redisRepository.clear();
}
@Test
public void testSet(){
redisRepository.valueSet("name", "robot");
redisRepository.valueSet("name2", "robot", 1600, TimeUnit.SECONDS);
redisRepository.valueSet("set:map", generateMap());
redisRepository.valueSet("set:map", generateMap(), 1600, TimeUnit.SECONDS);
redisRepository.valueSet("set:list", generateList());
redisRepository.valueSet("set:list", generateList(), 1600, TimeUnit.SECONDS);
}
@Test
public void testGet(){
logger.info("{}", redisRepository.valueGet("name", false));
logger.info("{}", redisRepository.valueGet("name2", true));
logger.info("{}", redisRepository.valueGet("set:map", false));
logger.info("{}", redisRepository.valueGet("set:map", true));
logger.info("{}", redisRepository.valueGet("set:list", false));
logger.info("{}", redisRepository.valueGet("set:list", true));
//logger.info("{}", redisRepository.getAndSet("name", "new value",false));
//logger.info("{}", redisRepository.getAndSet("name", "new value",true));
}
@Test
public void testIncrement(){
for (int i = 0; i < 10; i++) {
logger.info("{}", redisRepository.valueIncrement("mobile:15911111111", 1l, 60, TimeUnit.MINUTES));
logger.info("{}", redisRepository.valueIncrement("tel:15911111111", 1.0, 70, TimeUnit.MINUTES));
}
}
@Test
public void testSetArray(){
for (int i = 0; i < 10; i++) {
logger.info("{}", redisRepository.setAdd("set:array1",i));
}
for (int i = 5; i < 20; i++) {
logger.info("{}", redisRepository.setAdd("set:array1",i));
logger.info("{}", redisRepository.setAdd("set:array2",i));
}
//logger.info("{}", redisRepository.setPop("set:array"));
logger.info("{}", redisRepository.setDifference("set:array1","set:array2"));
logger.info("{}", redisRepository.setDifferenceAndStore("set:array1","set:array2", "set:array3"));
logger.info("{}", redisRepository.setAdd("set:add:map",generateMap()));
logger.info("{}", redisRepository.setAdd("set:add:list",generateList()));
logger.info("{}", redisRepository.setPop("set:add:map"));
logger.info("{}", redisRepository.setPop("set:add:list"));
}
@Test
public void testList(){
for (int i = 0; i < 10; i++) {
logger.info("{}", redisRepository.listLeftPush("list:lilo:list", generateList()));
logger.info("{}", redisRepository.listLeftPush("list:liro:list", generateList()));
logger.info("{}", redisRepository.listRightPush("list:rilo:list", generateList()));
logger.info("{}", redisRepository.listRightPush("list:riro:list", generateList()));
}
for (int i = 0; i < 5; i++) {
logger.info("{}", redisRepository.listLeftPop("list:lilo:list"));
logger.info("{}", redisRepository.listRightPop("list:liro:list"));
logger.info("{}", redisRepository.listLeftPop("list:rilo:list"));
logger.info("{}", redisRepository.listRightPop("list:riro:list"));
}
for (int i = 0; i < 10; i++) {
logger.info("{}", redisRepository.listLeftPush("list:lilo:map", generateMap()));
logger.info("{}", redisRepository.listLeftPush("list:liro:map", generateMap()));
logger.info("{}", redisRepository.listRightPush("list:rilo:map", generateMap()));
logger.info("{}", redisRepository.listRightPush("list:riro:map", generateMap()));
}
for (int i = 0; i < 5; i++) {
logger.info("{}", redisRepository.listLeftPop("list:lilo:map"));
logger.info("{}", redisRepository.listRightPop("list:liro:map"));
logger.info("{}", redisRepository.listLeftPop("list:rilo:map"));
logger.info("{}", redisRepository.listRightPop("list:riro:map"));
}
}
@Test
public void testZSet(){
for (int i = 0; i < 10; i++) {
logger.info("{}", redisRepository.zSetAdd("zset:map", generateMap(), i));
}
redisRepository.zSetIncrementScore("zset:Map", "4", 30);
}
@Test
public void testHash(){
for (int i = 0; i < 10; i++) {
redisRepository.hashPut("hash:map", String.valueOf(i), generateMap());
logger.info("{}", redisRepository.hashGet("hash:map", String.valueOf(i)));
}
for (int i = 0; i < 10; i++) {
redisRepository.hashPut("hash:list", String.valueOf(i), generateList());
logger.info("{}", redisRepository.hashGet("hash:list", String.valueOf(i)));
}
}
}
擴充套件
底層redis增刪改查封裝好之後,就很好擴充套件,如果想使用StringRedisTemplate,只需要簡單的繼承即可。
新建StringRedisRepository.java
@Repository(value = "stringRedisRepository")
public class StringRedisRepository extends AbstractSpringStringRedisCacheEnhance {
@Autowired StringRedisTemplate stringRedisTemplate;
@Override
public StringRedisTemplate getStringRedisTemplate() {
return stringRedisTemplate;
}
@Override
public RedisTemplate<String, Object> getRedisTemplate() {
return null;
}
}
測試類
/**
* @author heshiyuan
* @description <p></p>
* @path spring/com.hsy.spring.redis.dao
* @date 2018/7/24 10:13
* @github http://github.com/shiyuan2he
* @email [email protected]
* Copyright (c) 2018 [email protected] All rights reserved.
* @price ¥5 微信:hewei1109
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootRedisApplication.class)
public class StringRedisRepositoryTest {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired private StringRedisRepository stringRedisRepository;
@Test
public void testSet(){
stringRedisRepository.set("name", "robot");
stringRedisRepository.set("name", "robot", 60);
stringRedisRepository.set("name2", "robot", 1600, TimeUnit.SECONDS);
}
@Test
public void testGet(){
logger.info(stringRedisRepository.get("name", false));
logger.info(stringRedisRepository.get("name", true));
logger.info(stringRedisRepository.getAndSet("name", "new value",false));
logger.info(stringRedisRepository.getAndSet("name", "new value",true));
}
@Test
public void testIncrement(){
for (int i = 0; i < 10; i++) {
logger.info("{}", stringRedisRepository.increment("mobile:15911111111", 1l, 60, TimeUnit.MINUTES));
logger.info("{}", stringRedisRepository.increment("tel:15911111111", 1.0, 70, TimeUnit.MINUTES));
}
}
@Test
public void testSetArray(){
for (int i = 0; i < 10; i++) {
logger.info("{}", stringRedisRepository.addSet("set:array1",String.valueOf(i)));
}
for (int i = 5; i < 20; i++) {
logger.info("{}", stringRedisRepository.addSet("set:array1",String.valueOf(i)));
logger.info("{}", stringRedisRepository.addSet("set:array2",String.valueOf(i)));
}
//logger.info("{}", stringRedisRepository.popSet("set:array"));
logger.info("{}", stringRedisRepository.difference("set:array1","set:array2"));
logger.info("{}", stringRedisRepository.differenceAndStore("set:array1","set:array2", "set:array3"));
}
@Test
public void testList(){
for (int i = 0; i < 10; i++) {
logger.info("{}", stringRedisRepository.leftPush("list:lilo", String.valueOf(i)));
logger.info("{}", stringRedisRepository.leftPush("list:liro", String.valueOf(i)));
logger.info("{}", stringRedisRepository.rightPush("list:rilo", String.valueOf(i)));
logger.info("{}", stringRedisRepository.rightPush("list:riro", String.valueOf(i)));
}
for (int i = 0; i < 5; i++) {
logger.info("{}", stringRedisRepository.leftPop("list:lilo"));
logger.info("{}", stringRedisRepository.rightPop("list:liro"));
logger.info("{}", stringRedisRepository.leftPop("list:rilo"));
logger.info("{}", stringRedisRepository.rightPop("list:riro"));
}
}
@Test
public void testZSet(){
/* for (int i = 0; i < 10; i++) {
logger.info("{}", stringRedisRepository.addZSet("zset", String.valueOf(i), i+1));
}*/
stringRedisRepository.incrementScore("zset", "4", 30);
}
@Test
public void testHash(){
for (int i = 0; i < 10; i++) {
stringRedisRepository.put4Hash("hash", String.valueOf(i), String.valueOf(i));
logger.info("{}", stringRedisRepository.get("hash", String.valueOf(i)));
}
}
}
注意:
本文介紹StringRedisTemplate、RedisTemplate這兩個模板來介紹,其中StringRedisTemplate繼承自RedisTemplate,只能操作鍵值都是String型別的資料。在實際開發中建議使用RedisTemplate
原始碼
相關推薦
SpringBoot實戰之13 整合redis
工欲善其事必先利其器;預備一下工具對於整個環境的整合有極大的幫助 redisDesktopManage redis視覺化工具安裝 idea開發工具 開始 現如今,越來越多的公司注重使用者對網站訪問速度的體驗。而快取技術的出現無疑很好的適用以上場景
SpringBoot實戰之16 整合redis哨兵
前言 本篇介紹springboot整合哨兵模式 開始 建專案 新建springboot-redis-sentinel專案 新增maven依賴 <dependency> <groupId>o
SpringBoot實戰之8 整合jsp模版引擎
歷史文章 一、簡介 springboot支援多種模版引擎包括: 1. FreeMarker 2. Groovy 3. Thymeleaf (Spring 官網使用這個) 4. Velocity 5. JSP (貌似Spring Bo
SpringBoot(三)整合Redis
目前 setattr managing conn framework sset lan enable pla spring boot對常用的數據庫支持外,對nosql 數據庫也進行了封裝自動化。 redis介紹 Redis是目前業界使用最廣泛的內存數據存儲。相比me
SpringBoot實戰 之 接口日誌篇
empty 工具 argument contains art utm ioe strong exception 在本篇文章中不會詳細介紹日誌如何配置、如果切換另外一種日誌工具之類的內容,只用於記錄作者本人在工作過程中對日誌的幾種處理方式。 1. Debug 日誌管理 在開發
SpringBoot實戰之異常處理篇
mex 自身 gpo 模擬 all lpar 解決 return serve 在互聯網時代,我們所開發的應用大多是直面用戶的,程序中的任何一點小疏忽都可能導致用戶的流失,而程序出現異常往往又是不可避免的,那該如何減少程序異常對用戶體驗的影響呢
Apache CXF實戰之二 整合Sping與Web容器
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Springboot 2.0.x 整合Redis快取
文章目錄 Springboot 2.0.x 整合Redis快取 1、引入Redis快取依賴 2、配置Redis 資料庫 3、配置Redis CacheManager
SpringBoot(七) 整合redis
1、在pom檔案中新增如下配置 <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-st
SpringBoot(二)整合Redis-整合Mybatis
整合Redis 一:新增依賴 <!-- Redis依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifact
Springboot 學習之Swagger2整合
背景 在如今前後端分離的大背景下,前後端唯一打交道的就是API介面。前端只需要向後端請求url地址,後端只需將資料返回即可。前端工程師拿到的既是後端給到的一份完整的API文件,如果專案體量非常大的情況下,整理這些文件就需要浪費大量的時間。如果業務有變更的情況下
springboot專案練習五 整合redis-頁面靜態化
1 靜態化:根據請求連結生成html檔案完成訪問頁面的靜態化 2 靜態化借用nosql資料庫redis完成檔案儲存判斷 使用者發起請求,接收使用者請求,判斷是否已經生成html靜態檔案,有則直接將生成的HTML檔案地址return返回。 未生成html檔案,通過Http發起網
Redis實戰之徵服 Redis + Jedis + Spring (二)
不得不說,用雜湊操作來存物件,有點自討苦吃! 不過,既然吃了苦,也做個記錄,也許以後API升級後,能好用些呢?! 或許,是我的理解不對,沒有真正的理解雜湊表。 相關連結: 一、預期 接上一篇,擴充User屬性: Java程式碼 publiccla
springcloud實戰之13 rabbitmq訊息匯流排(bus)
rabbitmq是實現了高階訊息佇列協議(amqp)的開源訊息代理軟體,也成為面向訊息的中介軟體。RabbitMQ伺服器是用高效能,可伸縮而聞名的Erlang語言編寫而成的,其叢集和故障轉移是構建在開放電信平臺框架上的。 RabbitMQ的安裝這裡不重複說明,
Redis實戰之徵服 Redis + Jedis + Spring (三)
一開始以為Spring下操作雜湊表,列表,真就是那麼土。恍惚間發現“stringRedisTemplate.opsForList()”的強大,抓緊時間惡補下。 通過spring-data-redis完成LINDEX, LLEN, LPOP, LPUSH, LRANGE, L
SpringBoot 實戰 之 優雅終止服務
由於 SpringBoot 是一個微服務框架,其生產部署的方式也需要儘可能的簡單,與常規的 Web 應用有著一個巨大的不同之處,它可以內嵌一個 Web 容器,如:Tomcat、Jetty等,不再需要將應用打包成容器規定的特定形式。 對於 SpringBoot
SpringBoot實戰 之 異常處理篇
在網際網路時代,我們所開發的應用大多是直面使用者的,程式中的任何一點小疏忽都可能導致使用者的流失,而程式出現異常往往又是不可避免的,那該如何減少程式異常對使用者體驗的影響呢?其實方法很簡單,對異常進行捕獲,然後給予相應的處理即可。但實現的方式卻有好多種,例如:
spring實戰4 spring整合redis哨兵
前言 開始 建專案 新建spring-redis-sentinel web專案 導包 <dependency> <groupId>org.springframework</groupId>
SpringBoot系列之i18n整合教程
目錄 1、環境搭建 2、resource bundle資源配置 3、LocaleResolver類 4、I18n配置類 5、Thymeleaf整合 SpringB
例項講解Springboot以Template方式整合Redis及序列化問題
1 簡介 之前講過如何通過Docker安裝Redis,也講了Springboot以Repository方式整合Redis,建議閱讀後再看本文效果更佳: (1) Docker安裝Redis並介紹漂亮的視覺化客戶端進行操作 (2) 例項講解Springboot以Repository方式整合Redis 本文將通過例