1. 程式人生 > >Springboot+Jedis+Ehcache整合

Springboot+Jedis+Ehcache整合

專案結構概覽:

1. 導包

      <parent> 
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> 
    </parent>
    <properties
> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!--
web場景啟動器,包含 Tomcat 和 spring-mvc restful aop jackjson支援。 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 熱載入 --> <dependency
> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- ehcache快取 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <!-- redis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <type>jar</type> <scope>compile</scope> </dependency> <!-- 熱載入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <!-- commons-lang3工具類 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

2.1 application.properties配置檔案

# 執行埠
server.port=8084
# 專案訪問路徑字首
server.context-path=/cache

# 服務名稱
spring.application.name=springbootTest
# ehcache配置檔案
spring.cache.ehcache.config=classpath:ehcacheproduct.xml

2.2 redis.properties配置引數

# Redis資料庫索引(預設為0)
spring.redis.database=0
# Redis伺服器地址
spring.redis.host=127.0.0.1
# Redis伺服器連線埠
spring.redis.port=6379
# Redis伺服器連線密碼(預設為空)
#spring.redis.password=
# 連線池最大連線數(使用負值表示沒有限制)
spring.redis.jedis.pool.max-active=1024
# 連線池最大阻塞等待時間(使用負值表示沒有限制)
spring.redis.jedis.pool.max-wait=10000
# 連線池中的最大空閒連線
spring.redis.jedis.pool.max-idle=200
# 連線池中的最小空閒連線
spring.redis.jedis.pool.min-idle=0
# 連線超時時間(毫秒)
spring.redis.timeout=10000
#flase:超時就報錯,   true:阻塞到超時
spring.redis.block-when-exhausted=true

2.3 ehcacheproduct.xml配置問價

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd">
    
    <!-- 磁碟快取位置 -->
    <diskStore path="java.io.tmpdir" />
    
    <!-- 
        name: 快取名稱
        maxElementsInMemory: 快取最大個數
        maxEntriesLocalHeap: 在記憶體建立物件的最大數量,0=無限制。
        maxEntriesLocalDisk: 硬碟上儲存的物件的最大數量。預設0,即無限制
        eternal: 物件是否永久有效,一但設定了, timeout將不起作用
        timeToIdleSeconds: 當快取閒置n秒後銷燬 ,預設是0,也就是物件存活時間無窮大。當eternal=false時有效!
        timeToLiveSeconds: 當快取存活n秒後銷燬 ,預設是0,也就是物件存活時間無窮大。當eternal=false時有效!
        overflowToDisk: 達到快取maxElementsInMemory個數後,將資料存入磁碟,預設大小為30mb
        diskPersistent: 是否快取虛擬機器重啟期資料 
        diskExpiryThreadIntervalSeconds: 磁碟失效執行緒執行時間間隔,預設是120秒。達到快取最大個數,會按照磁碟清理策略去清理磁碟。
        memoryStoreEvictionPolicy: 磁碟清理策略, 預設策略LRU(最近最少使用)你可以設定為FIFO(先進先出)或是LFU(較少使用)。
        clearOnFlush: 記憶體數量最大時是否清除
     -->
    <!-- 預設快取 -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">

        <persistence strategy="localTempSwap" />
    </defaultCache>

    <!-- 自定義快取 -->
    <cache name="userchache"
           eternal="false"
           timeToIdleSeconds="2400"
           timeToLiveSeconds="2400"
           maxEntriesLocalHeap="10000"
           maxEntriesLocalDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU">
    </cache>
</ehcache>

3. RedisConfig配置檔案

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
@Configuration
@PropertySource("classpath:redis.properties")
public class RedisConfig {
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    @Value("${spring.redis.host}")
    private String host;
 
    @Value("${spring.redis.port}")
    private int port;
 
    @Value("${spring.redis.timeout}")
    private int timeout;
 
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
 
    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;
 
    //@Value("${spring.redis.password}")
    //private String password;
    private String password;
    
    @Value("${spring.redis.block-when-exhausted}")
    private boolean  blockWhenExhausted;
 
    @Bean
    public JedisPool redisPoolFactory()  throws Exception{
        log.info("-------------JedisPool注入成功!!----------------");
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 連線耗盡時是否阻塞, false報異常,ture阻塞直到超時, 預設true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否啟用pool的jmx管理功能, 預設true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
        
        return jedisPool;
    }
}

4. Redis工具類

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
@Component
public class RedisUtil{
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private JedisPool jedisPool;
 
    
    public String get(String key) {
        Jedis jedis = null;
        String value = null;
        try {
            jedis = jedisPool.getResource();
            value = jedis.get(key);
            log.info(value);
        } catch (Exception e) {
 
            log.error(e.getMessage());
        } finally {
            returnResource(jedis);
        }
        return value;
    }    
    
    public String set(String key, String value) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            return jedis.set(key, value);
        } catch (Exception e) {
 
            log.error(e.getMessage());
            return "0";
        } finally {
            returnResource(jedis);
        }
    }
    
    /**
     * 關閉連線
     */
    public static void returnResource(Jedis jedis) {
        try {
            jedis.close();
        } catch (Exception e) {
        }
    }
}    

5. 測試業務邏輯

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.wulei.model.User;
import com.wulei.utils.RedisUtil;
@Service
// 指定ehcache快取規則
@CacheConfig(cacheNames = "userchache")
public class UserService {
    @Autowired
    RedisUtil redisUtil;
    
    public List<User> testRedis() {
        redisUtil.set("name", "吳磊");
        System.out.println(redisUtil.get("name"));
        return this.getDataSource();
    }
    
    @Cacheable(key="'testEhcaheCacheable'")
    public List<User> testEhcaheCacheable(){
        // 只會查詢一次
        System.out.println("Cacheable查詢快取資料");
        return this.getDataSource();
    }
    
    //鍵為"userId:"字串加上userId值,如 'userId:1'
    @CacheEvict(key="'userId:' + #userId")
    public List<User> testEhcaheCacheEvict(int userId){
        // 每次請求都會刪除指定key
        System.out.println("清除userchache中指定key的快取");
        List<User> list = this.getDataSource();
        list.remove(userId-1);
        return list;
    }
    
    @CacheEvict(allEntries=true)  
    public List<User> testEhcaheCacheEvictAll(){
        // 每次請求都會刪除所有key
        System.out.println("清除userchache中所有key的快取");
        return new ArrayList<User>();
    }
    
    public List<User> getDataSource(){
        List<User> list = new ArrayList<User>();
        list.add(new User(1, "jay", 21));
        list.add(new User(2, "join", 22));
        list.add(new User(3, "eason", 23));
        list.add(new User(4, "jj", 24));
        return list;
    }
}

6. controller入口

@RestController
public class UserController {

    @Autowired
    private UserService userService;
    
    @RequestMapping("/testRedis")
    public List<User> testRedis() {
        return userService.testRedis();
    }
    @RequestMapping("/testEhcahe")
    public List<User> testEhcahe(int type){
        if(type==1) {
            return userService.testEhcaheCacheable();
        }else if(type==2) {
            return userService.testEhcaheCacheEvict(type);
        }else if(type==3) {
            return userService.testEhcaheCacheEvictAll();
        }
        return null;
    }
}

7. 主函式

@SpringBootApplication
@EnableCaching // 啟用ehcache快取註解
public class Application {

     private static Logger log = Logger.getLogger(Application.class);
     
     public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
            log.info("SpringBoot Start Success");
        }
}