windows環(huán)境下Redis+Spring緩存實(shí)例講解
一、Redis了解
1.1、Redis介紹:
redis是一個(gè)key-value存儲(chǔ)系統(tǒng)。和Memcached類似,它支持存儲(chǔ)的value類型相對(duì)更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會(huì)周期性的把更新的數(shù)據(jù)寫(xiě)入磁盤(pán)或者把修改操作寫(xiě)入追加的記錄文件,并且在此基礎(chǔ)上實(shí)現(xiàn)了master-slave(主從)同步。
Redis數(shù)據(jù)庫(kù)完全在內(nèi)存中,使用磁盤(pán)僅用于持久性。相比許多鍵值數(shù)據(jù)存儲(chǔ),Redis擁有一套較為豐富的數(shù)據(jù)類型。Redis可以將數(shù)據(jù)復(fù)制到任意數(shù)量的從服務(wù)器。
1.2、Redis優(yōu)點(diǎn):
(1)異??焖伲篟edis的速度非常快,每秒能執(zhí)行約11萬(wàn)集合,每秒約81000+條記錄。
(2)支持豐富的數(shù)據(jù)類型:Redis支持最大多數(shù)開(kāi)發(fā)人員已經(jīng)知道像列表,集合,有序集合,散列數(shù)據(jù)類型。這使得它非常容易解決各種各樣的問(wèn)題,因?yàn)槲覀冎滥男﹩?wèn)題是可以處理通過(guò)它的數(shù)據(jù)類型更好。
(3)操作都是原子性:所有Redis操作是原子的,這保證了如果兩個(gè)客戶端同時(shí)訪問(wèn)的Redis服務(wù)器將獲得更新后的值。
(4)多功能實(shí)用工具:Redis是一個(gè)多實(shí)用的工具,可以在多個(gè)用例如緩存,消息,隊(duì)列使用(Redis原生支持發(fā)布/訂閱),任何短暫的數(shù)據(jù),應(yīng)用程序,如Web應(yīng)用程序會(huì)話,網(wǎng)頁(yè)命中計(jì)數(shù)等。
1.3、Redis缺點(diǎn):
(1)單線程
(2)耗內(nèi)存
二、64位windows下Redis安裝
Redis官方是不支持windows的,但是Microsoft Open Tech group 在 GitHub上開(kāi)發(fā)了一個(gè)Win64的版本,下載地址:https://github.com/MSOpenTech/redis/releases。注意只支持64位哈。
小寶鴿是下載了Redis-x64-3.0.500.msi進(jìn)行安裝。安裝過(guò)程中全部采取默認(rèn)即可。
安裝完成之后可能已經(jīng)幫你開(kāi)啟了Redis對(duì)應(yīng)的服務(wù),博主的就是如此。查看資源管理如下,說(shuō)明已經(jīng)開(kāi)啟:
已經(jīng)開(kāi)啟了對(duì)應(yīng)服務(wù)的,我們讓它保持,下面例子需要用到。如果沒(méi)有開(kāi)啟的,我們命令開(kāi)啟,進(jìn)入Redis的安裝目錄(博主的是C:\Program Files\Redis),然后如下命令開(kāi)啟:
redis-server redis.windows.conf
OK,下面我們進(jìn)行實(shí)例。
三、詳細(xì)實(shí)例
本工程采用的環(huán)境:Eclipse + maven + spring + junit
3.1、添加相關(guān)依賴(spring+junit+redis依賴),pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.luo</groupId> <artifactId>redis_project</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <!-- spring版本號(hào) --> <spring.version>3.2.8.RELEASE</spring.version> <!-- junit版本號(hào) --> <junit.version>4.10</junit.version> </properties> <dependencies> <!-- 添加Spring依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!--單元測(cè)試依賴 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!--spring單元測(cè)試依賴 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- Redis 相關(guān)依賴 --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.6.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.3</version> </dependency> </dependencies> </project>
3.2、spring配置文件application.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 自動(dòng)掃描注解的bean --> <context:component-scan base-package="com.luo.service" /> <!-- 引入properties配置文件 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:properties/*.properties</value> <!--要是有多個(gè)配置文件,只需在這里繼續(xù)添加即可 --> </list> </property> </bean> <!-- jedis 配置 --> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" > <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWaitMillis" value="${redis.maxWait}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> </bean > <!-- redis服務(wù)器中心 --> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > <property name="poolConfig" ref="poolConfig" /> <property name="port" value="${redis.port}" /> <property name="hostName" value="${redis.host}" /> <!-- <property name="password" value="${redis.password}" /> --> <property name="timeout" value="${redis.timeout}" ></property> </bean > <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" > <property name="connectionFactory" ref="connectionFactory" /> <property name="keySerializer" > <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> <property name="valueSerializer" > <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" /> </property> </bean > <!-- cache配置 --> <bean id="methodCacheInterceptor" class="com.luo.redis.cache.MethodCacheInterceptor" > <property name="redisTemplate" ref="redisTemplate" /> </bean > <!-- aop配置切點(diǎn)跟通知 --> <bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="methodCacheInterceptor"/> <property name="pattern" value=".*ServiceImpl.*getTimestamp"/> </bean> <bean id="redisTestService" class="com.luo.service.impl.RedisTestServiceImpl"> </bean> <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/> </beans>
3.3、Redis配置參數(shù),redis.properties:
#redis中心 #綁定的主機(jī)地址 redis.host=127.0.0.1 #指定Redis監(jiān)聽(tīng)端口,默認(rèn)端口為6379 redis.port=6379 #授權(quán)密碼(本例子沒(méi)有使用) redis.password=123456 #最大空閑數(shù):空閑鏈接數(shù)大于maxIdle時(shí),將進(jìn)行回收 redis.maxIdle=100 #最大連接數(shù):能夠同時(shí)建立的“最大鏈接個(gè)數(shù)” redis.maxActive=300 #最大等待時(shí)間:?jiǎn)挝籱s redis.maxWait=1000 #使用連接時(shí),檢測(cè)連接是否成功 redis.testOnBorrow=true #當(dāng)客戶端閑置多長(zhǎng)時(shí)間后關(guān)閉連接,如果指定為0,表示關(guān)閉該功能 redis.timeout=10000
3.4、添加接口及對(duì)應(yīng)實(shí)現(xiàn)RedisTestService.Java和RedisTestServiceImpl.java:
package com.luo.service; public interface RedisTestService { public String getTimestamp(String param); }
package com.luo.service.impl; import org.springframework.stereotype.Service; import com.luo.service.RedisTestService; @Service public class RedisTestServiceImpl implements RedisTestService { public String getTimestamp(String param) { Long timestamp = System.currentTimeMillis(); return timestamp.toString(); } }
3.5、本例采用spring aop切面方式進(jìn)行緩存,配置已在上面spring配置文件中,對(duì)應(yīng)實(shí)現(xiàn)為MethodCacheInterceptor.java:
package com.luo.redis.cache; import java.io.Serializable; import java.util.concurrent.TimeUnit; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; public class MethodCacheInterceptor implements MethodInterceptor { private RedisTemplate<Serializable, Object> redisTemplate; private Long defaultCacheExpireTime = 10l; // 緩存默認(rèn)的過(guò)期時(shí)間,這里設(shè)置了10秒 public Object invoke(MethodInvocation invocation) throws Throwable { Object value = null; String targetName = invocation.getThis().getClass().getName(); String methodName = invocation.getMethod().getName(); Object[] arguments = invocation.getArguments(); String key = getCacheKey(targetName, methodName, arguments); try { // 判斷是否有緩存 if (exists(key)) { return getCache(key); } // 寫(xiě)入緩存 value = invocation.proceed(); if (value != null) { final String tkey = key; final Object tvalue = value; new Thread(new Runnable() { public void run() { setCache(tkey, tvalue, defaultCacheExpireTime); } }).start(); } } catch (Exception e) { e.printStackTrace(); if (value == null) { return invocation.proceed(); } } return value; } /** * 創(chuàng)建緩存key * * @param targetName * @param methodName * @param arguments */ private String getCacheKey(String targetName, String methodName, Object[] arguments) { StringBuffer sbu = new StringBuffer(); sbu.append(targetName).append("_").append(methodName); if ((arguments != null) && (arguments.length != 0)) { for (int i = 0; i < arguments.length; i++) { sbu.append("_").append(arguments[i]); } } return sbu.toString(); } /** * 判斷緩存中是否有對(duì)應(yīng)的value * * @param key * @return */ public boolean exists(final String key) { return redisTemplate.hasKey(key); } /** * 讀取緩存 * * @param key * @return */ public Object getCache(final String key) { Object result = null; ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); result = operations.get(key); return result; } /** * 寫(xiě)入緩存 * * @param key * @param value * @return */ public boolean setCache(final String key, Object value, Long expireTime) { boolean result = false; try { ValueOperations<Serializable, Object> operations = redisTemplate .opsForValue(); operations.set(key, value); redisTemplate.expire(key, expireTime, TimeUnit.SECONDS); result = true; } catch (Exception e) { e.printStackTrace(); } return result; } public void setRedisTemplate( RedisTemplate<Serializable, Object> redisTemplate) { this.redisTemplate = redisTemplate; } }
3.6、單元測(cè)試相關(guān)類:
package com.luo.baseTest; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; //指定bean注入的配置文件 @ContextConfiguration(locations = { "classpath:application.xml" }) //使用標(biāo)準(zhǔn)的JUnit @RunWith注釋來(lái)告訴JUnit使用Spring TestRunner @RunWith(SpringJUnit4ClassRunner.class) public class SpringTestCase extends AbstractJUnit4SpringContextTests { }
package com.luo.service; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import com.luo.baseTest.SpringTestCase; public class RedisTestServiceTest extends SpringTestCase { @Autowired private RedisTestService redisTestService; @Test public void getTimestampTest() throws InterruptedException{ System.out.println("第一次調(diào)用:" + redisTestService.getTimestamp("param")); Thread.sleep(2000); System.out.println("2秒之后調(diào)用:" + redisTestService.getTimestamp("param")); Thread.sleep(11000); System.out.println("再過(guò)11秒之后調(diào)用:" + redisTestService.getTimestamp("param")); } }
3.7、運(yùn)行結(jié)果:
四、源碼下載:redis-project(jb51.net).rar
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
了解redis中RDB結(jié)構(gòu)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了redis中RDB結(jié)構(gòu),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Redis從單點(diǎn)到集群部署模式(單機(jī)模式?主從模式?哨兵模式)
這篇文章主要為大家介紹了Redis從單點(diǎn)集群部署模式(單機(jī)模式?主從模式?哨兵模式)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11Redis整合SpringBoot的RedisTemplate實(shí)現(xiàn)類(實(shí)例詳解)
這篇文章主要介紹了Redis整合SpringBoot的RedisTemplate實(shí)現(xiàn)類,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Redis使用bloom-filter過(guò)濾器實(shí)現(xiàn)推薦去重
這篇文章主要介紹了Redis使用bloom-filter過(guò)濾器實(shí)現(xiàn)推薦去重,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11