- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章浅谈SpringCache与redis集成实现缓存解决方案由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
缓存可以说是加速服务响应速度的一种非常有效并且简单的方式。在缓存领域,有很多知名的框架,如ehcache 、guava、hazelcast等。redis作为key-value型数据库,由于他的这一特性,redis也成为一种流行的数据缓存工具.
在传统方式下对于缓存的处理代码是非常臃肿的.
例如:我们要把一个查询函数加入缓存功能,大致需要三步.
1、在函数执行前,我们需要先检查缓存中是否存在数据,如果存在则返回缓存数据 。
2、如果不存在,就需要在数据库的数据查询出来.
3、最后把数据存放在缓存中,当下次调用此函数时,就可以直接使用缓存数据,减轻了数据库压力.
那么实现上面的三步需要多少代码呢?下面是一个示例:
。
上图中的红色部分都是模板代码,真正与这个函数有关的代码却只占了1/5,对于所有需要实现缓存功能的函数,都需要加上臃肿的模板代码。可谓是一种极不优雅的解决方案.
那么如何让臃肿的代码重回清新的当初呢?
aop不就是专门解决这种模板式代码的最佳方案吗,幸运的是我们不需要再自己实现切面了,springcache已经为我们提供好了切面,我们只需要进行简单的配置,就可以重回当初了,像下面这样:
只需要加一个注解就可以了,对于原来的代码连改都不需要改,是不是已经跃跃欲试了?
对于配置springcache只需要三步:
第一步:加入相关依赖:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<dependency>
<groupid>redis.clients</groupid>
<artifactid>jedis</artifactid>
<version>
2.9
.
0
</version>
</dependency>
<dependency>
<groupid>org.springframework.data</groupid>
<artifactid>spring-data-redis</artifactid>
<version>
1.6
.
0
.release</version>
</dependency>
<dependency>
<groupid>org.apache.commons</groupid>
<artifactid>commons-lang3</artifactid>
<version>
3.3
.
2
</version>
</dependency>
|
第二步:配置springcache,redis连接等信息 。
applicationcontext-redis.xml 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
<?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:p=
"http://www.springframework.org/schema/p"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:mvc=
"http://www.springframework.org/schema/mvc"
xmlns:cache=
"http://www.springframework.org/schema/cache"
xsi:schemalocation="http:
//www.springframework.org/schema/beans
http:
//www.springframework.org/schema/beans/spring-beans-4.2.xsd
http:
//www.springframework.org/schema/context
http:
//www.springframework.org/schema/context/spring-context-4.2.xsd
http:
//www.springframework.org/schema/mvc
http:
//www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http:
//www.springframework.org/schema/cache
http:
//www.springframework.org/schema/cache/spring-cache-4.2.xsd">
<!-- 配置文件加载 -->
<context:property-placeholder location=
"classpath:*.properties"
/>
<cache:annotation-driven cache-manager=
"cachemanager"
/>
<!-- redis连接池 -->
<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>
<!-- 连接工厂 -->
<bean id=
"jedisconnectionfactory"
class
=
"org.springframework.data.redis.connection.jedis.jedisconnectionfactory"
p:host-name=
"${redis.host}"
p:port=
"${redis.port}"
p:password=
"${redis.pass}"
p:pool-config-ref=
"poolconfig"
/>
<!-- redis模板 -->
<bean id=
"redistemplate"
class
=
"org.springframework.data.redis.core.redistemplate"
>
<property name=
"connectionfactory"
ref=
"jedisconnectionfactory"
/>
</bean>
<bean id=
"cachemanager"
class
=
"org.springframework.cache.support.simplecachemanager"
>
<property name=
"caches"
>
<set>
<!-- 这里可以配置多个redis -->
<bean
class
=
"com.cky.rest.utils.rediscache"
>
<property name=
"redistemplate"
ref=
"redistemplate"
/>
<property name=
"name"
value=
"content"
/>
<!-- name对应的名称要在类或方法的注解中使用 -->
</bean>
</set>
</property>
</bean>
</beans>
|
redis.properties文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
# redis settings
# server ip
redis.host=
192.168
.
100.55
# server port
redis.port=
6379
# server pass
redis.pass=
# use dbindex
redis.database=
0
#max idel instance of jedis
redis.maxidle=
300
#
if
wait too
long
,
throw
jedisconnectionexception
redis.maxwait=
3000
#
if
true
,it will validate before borrow jedis instance,what you get instance is all usefull
redis.testonborrow=
true
|
第三步,编写cache接口实现类 。
spring对于缓存只是提供了抽象的接口,并且通过接口来调用功能,没有具体的实现类,所以需要我们自己实现具体的操作.
在上面配置中可知,每个实现类都会注入一个redistemplate实例,我们就可以通过redistemplate来操作redis 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
package
com.cky.rest.utils;
import
java.io.serializable;
import
org.apache.commons.lang3.serializationutils;
import
org.springframework.cache.cache;
import
org.springframework.cache.support.simplevaluewrapper;
import
org.springframework.dao.dataaccessexception;
import
org.springframework.data.redis.connection.redisconnection;
import
org.springframework.data.redis.core.rediscallback;
import
org.springframework.data.redis.core.redistemplate;
public
class
rediscache
implements
cache {
private
redistemplate<string, object> redistemplate;
private
string name;
@override
public
void
clear() {
system.out.println(
"-------緩存清理------"
);
redistemplate.execute(
new
rediscallback<string>() {
@override
public
string doinredis(redisconnection connection)
throws
dataaccessexception {
connection.flushdb();
return
"ok"
;
}
});
}
@override
public
void
evict(object key) {
system.out.println(
"-------緩存刪除------"
);
final
string keyf=key.tostring();
redistemplate.execute(
new
rediscallback<
long
>() {
@override
public
long
doinredis(redisconnection connection)
throws
dataaccessexception {
return
connection.del(keyf.getbytes());
}
});
}
@override
public
valuewrapper get(object key) {
system.out.println(
"------缓存获取-------"
+key.tostring());
final
string keyf = key.tostring();
object object =
null
;
object = redistemplate.execute(
new
rediscallback<object>() {
@override
public
object doinredis(redisconnection connection)
throws
dataaccessexception {
byte
[] key = keyf.getbytes();
byte
[] value = connection.get(key);
if
(value ==
null
) {
system.out.println(
"------缓存不存在-------"
);
return
null
;
}
return
serializationutils.deserialize(value);
}
});
valuewrapper obj=(object !=
null
?
new
simplevaluewrapper(object) :
null
);
system.out.println(
"------获取到内容-------"
+obj);
return
obj;
}
@override
public
void
put(object key, object value) {
system.out.println(
"-------加入缓存------"
);
system.out.println(
"key----:"
+key);
system.out.println(
"key----:"
+value);
final
string keystring = key.tostring();
final
object valuef = value;
final
long
livetime =
86400
;
redistemplate.execute(
new
rediscallback<
long
>() {
@override
public
long
doinredis(redisconnection connection)
throws
dataaccessexception {
byte
[] keyb = keystring.getbytes();
byte
[] valueb = serializationutils.serialize((serializable) valuef);
connection.set(keyb, valueb);
if
(livetime >
0
) {
connection.expire(keyb, livetime);
}
return
1l;
}
});
}
@override
public
<t> t get(object arg0,
class
<t> arg1) {
// todo auto-generated method stub
return
null
;
}
@override
public
string getname() {
return
this
.name;
}
@override
public
object getnativecache() {
return
this
.redistemplate;
}
@override
public
valuewrapper putifabsent(object arg0, object arg1) {
// todo auto-generated method stub
return
null
;
}
public
redistemplate<string, object> getredistemplate() {
return
redistemplate;
}
public
void
setredistemplate(redistemplate<string, object> redistemplate) {
this
.redistemplate = redistemplate;
}
public
void
setname(string name) {
this
.name = name;
}
}
|
在配置过程中曾经出现过两次错误:
1.xxxx.classnotfoundexception 最后发现是jar下载不完整,把maven本地仓库的对应jar包文件夹删除完从新下载就好了 。
2.xxxx.methodnotfoundexception 这种情况是版本不对,换成第一步中的版本就可以了 。
springcache中常见注解的使用:
@cacheable注解 。
最常用的注解,会把被注解方法的返回值缓存。工作原理是:首先在缓存中查找,如果没有执行方法并缓存结果,然后返回数据。此注解的缓存名必须指定,和cachemanager中的caches中的某一个cache的name值相对应。可以使用value或cachenames指定.
如果没有指定key属性,spring会使用默认的主键生成器产生主键。也可以自定义主键,在key中可以使用spel表达式。如下:
1
2
3
4
|
@cacheable
(cachenames=”content”,key=”#user.userid”)
public
user getuser(user user){
xxxxx
}
|
可以使用condition属性,来给缓存添加条件,如下:
1
2
|
@cacheable
(cachenames=”content”,key=”#user.userid”,condition=”#user.age<
40
”)
public
user getuser(user user){xxxxx}
|
@cacheput注解 。
先执行方法,然后将返回值放回缓存。可以用作缓存的更新.
@cacheevict注解 。
该注解负责从缓存中显式移除数据,通常缓存数据都有有效期,当过期时数据也会被移除.
此注解多了两个属性:
allentries是否移除所有缓存条目.
beforeinvocation:在方法调用前还是调用后完成移除操作。true/false 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:http://www.cnblogs.com/chenkeyu/p/8028781.html 。
最后此篇关于浅谈SpringCache与redis集成实现缓存解决方案的文章就讲到这里了,如果你想了解更多关于浅谈SpringCache与redis集成实现缓存解决方案的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我只是想知道要安装哪个版本的 Visual Studio 2010(专业版或高级版)提示升级项目.. 项目包括:asp.net mvc、数据库和silverlight。 最佳答案 通常,由不同版本的相
几种通过 iproute2 来打通不同节点间容器网络的方式 几种通过 iproute2 来打通不同节点间容器网络的方式 host-gw ipip vxlan 背景 之前由于需
目录 前言 1、TypeHandler 简介 1.1转换步骤 1.2转换规则 2、JSON 转换 3、枚举转换 4、文章小结
目录 前言 1、常见 key-value 2、时效性强 3、计数器相关 4、高实时性 5、排行榜系列 6、文章小结 前言 在笔者 3 年的
目录 前言 四、技术选型 五、后端接口设计 5.1业务系统接口 5.2App 端接口 六、关键逻辑实现 6.1Red
目录 前言 一、需求分析 1.1发送通知 1.2撤回通知 1.3通知消息数 1.4通知消息列表 二、数据模型设计
目录 前言 一、多租户的概念 二、隔离模式 2.1独立数据库模式 2.2共享数据库独立数据架构 2.3共享数据库共享数据架构
导读: 虽然锁在一定程度上能够解决并发问题,但稍有不慎,就可能造成死锁。本文介绍死锁的产生及处理。 死锁的产生和预防 发生死锁的必要条件有4个,分别为互斥条件、不可剥夺条件、请求与保持条件和循环等待条
在浏览网页后,我找不到任何功能来执行此操作,我有可行的个人解决方案。也许它对某人有用。 **使用 Moment 插件转换日期。***moment(currentPersianDate).clone()
是否有一种解决方案可以很好地处理数字(1-10)手写?我试过tesseract,但我得到的只是垃圾。 理想情况下是 OSS,但商业也可以。 最佳答案 OpenCV 现在带有手写数字识别 OCR 示例。
在服务器应用程序上,我们有以下内容:一个称为 JobManager 的单例类。另一个类,Scheduler,不断检查是否需要向 JobManager 添加任何类型的作业。 当需要这样做时,调度程序会执
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 5年前关闭。 Improve this qu
当您尝试从 GitHub 存储库安装某些 R 包时 install_github('rWBclimate', 'ropensci') 如果您遇到以下错误: Installing github repo
问题在以下链接中进行了描述和演示: Paul Stovell WPF: Blurry Text Rendering www.gamedev.net forum Microsoft Connect: W
我正在寻找一种解决方案,使用标准格式 a × 10 b 在科学记数法下格式化 R 中的数字。一些同行评审的科学期刊都要求这样做,并且手动修改图表可能会变得乏味。 下面是 R 标准“E 表示法”的示例,
已编辑解决方案(如下...) 我有一个启动画面,它被打包到它自己的 jar 中。它有效。 我可以通过以下方式从另一个 java 应用程序内部调用 Splash.jar: Desktop.getDesk
什么是创建像 PageFlakes 或 iGoogle 这样的门户网站的好框架/包? ?我们希望创建一个为员工提供 HR 服务的员工/HR 门户,但我们也需要一种足够灵活的产品,以便我们可以使用它来为
我正在寻找一种解决方案,使用标准格式 a × 10 b 在科学记数法下格式化 R 中的数字。一些同行评审的科学期刊都要求这样做,并且手动修改图表可能会变得乏味。 下面是 R 标准“E 表示法”的示例,
如何将 solr 与 heritrix 集成? 我想使用 heritrix 归档一个站点,然后使用 solr 在本地索引和搜索该文件。 谢谢 最佳答案 使用 Solr 进行索引的问题在于它是一个纯文本
完整日历不包含工作时间功能选项(在任何一天的议程 View 中选择第一行和最后一行 - 例如公司不工作)。我做到了类似的事情: viewDisplay: function(view){
我是一名优秀的程序员,十分优秀!