Redis+EJB实现缓存(一)
如今脑子相对照较清晰了一些。
实现思路
缓存的功能是和业务无关的,为的是提高程序的性能。
也就是说能够将程序和缓存看作是两个平行的功能。
那么在这样的情况下就能够借助AOP的思想来将缓存引入到程序中,已实现缓存功能在一个程序中的重用问题。
那么多程序的情况下,这就仅仅能打成jar包引用到各个程序中去了。EJB中没有像spring aop一样的完整的机制,可是能够借助拦截器来实现缓存功能的切入。
这里,EJB容器的作用就是识别拦截标志。然后交给拦截器去处理,拦截器在调用缓存client运行缓存的操作。以下就看看实现。
client的开发
- 引入相关的Jar包(基于maven项目)
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;"> <dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.0</version>
<type>ejb</type>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>6.0</version>
<type>ejb</type>
</dependency></span></span>
- 面对Jedis的缓存管理类(RedisManager)
这个类,包含与redis数据库的链接的创建和管理,以及对数据存储操作。这个类的操作的都是byte型的数据。因此还须要封装一层面对使用者相对有好的缓存管理类。
<span style="font-family:FangSong_GB2312;font-size:18px;">private String host = "127.0.0.1";
private int port = 6379;
private int expire = 0;
private int timeout = 0;
private String password = "";
private static JedisPool jedisPool = null;
public RdisManager(){
}
/**
* 初始化方法
*/
public void init(){
if(jedisPool == null){
if(password != null && !"".equals(password)){
jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password);
}else if(timeout != 0){
jedisPool = new JedisPool(new JedisPoolConfig(), host, port,timeout);
}else{
jedisPool = new JedisPool(new JedisPoolConfig(), host, port);
}
}
}
/**
* 从redis依据key值取得value
* @param key
* @return
*/
public byte[] get(byte[] key){
byte[] value = null;
Jedis jedis = jedisPool.getResource();
try{
value = jedis.get(key);
}finally{
jedisPool.returnResource(jedis);
}
return value;
}
/**
* 将value创建一个key值存入redis
* @param key
* @param value
* @return
*/
public byte[] set(byte[] key,byte[] value){
Jedis jedis = jedisPool.getResource();
try{
jedis.set(key,value);
if(this.expire != 0){
jedis.expire(key, this.expire);
}
}finally{
jedisPool.returnResource(jedis);
}
return value;
}
/**
* 存入Key-Vlaue键值对和过期时间
* @param key
* @param value
* @param expire
* @return
*/
public byte[] set(byte[] key,byte[] value,int expire){
Jedis jedis = jedisPool.getResource();
try{
jedis.set(key,value);
if(expire != 0){
jedis.expire(key, expire);
}
}finally{
jedisPool.returnResource(jedis);
}
return value;
}
/**
* 依据key值删除value
* @param key
*/
public void del(byte[] key){
Jedis jedis = jedisPool.getResource();
try{
jedis.del(key);
}finally{
jedisPool.returnResource(jedis);
}
}
/**
* 清空当前数据库
*/
public void flushDB(){
Jedis jedis = jedisPool.getResource();
try{
jedis.flushDB();
}finally{
jedisPool.returnResource(jedis);
}
}
/**
* key值的总数
*/
public Long dbSize(){
Long dbSize = 0L;
Jedis jedis = jedisPool.getResource();
try{
dbSize = jedis.dbSize();
}finally{
jedisPool.returnResource(jedis);
}
return dbSize;
}
/**
* keys
* @param regex
* @return
*/
public Set<byte[]> keys(String pattern){
Set<byte[]> keys = null;
Jedis jedis = jedisPool.getResource();
try{
keys = jedis.keys(pattern.getBytes());
}finally{
jedisPool.returnResource(jedis);
}
return keys;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getExpire() {
return expire;
}
public void setExpire(int expire) {
this.expire = expire;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}</span>
- 面对用户的缓存操作类(Cache)
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">public class Cache {
/**
* 持有redis管理器
*/
private RedisManager cacheManager=new RedisManager();
/**
* @param key
* @return
* @author 卓家进
* @Date 2015年3月9日下午9:23:59
*/
public String get(String key){
byte result[] = cacheManager.get(DataTypeUtils.stringToByte(key));
return DataTypeUtils.btyeToString(result);
}
/**
* key-value相应写入
* @param key值
* @param value缓存数据
* @author 卓家进
* @Date 2015年3月10日下午4:02:39
*/
public void set(String key,String value){
cacheManager.set(DataTypeUtils.stringToByte(key),
SerializeUtils.serialize(value));
}
/**
* 依据key值删除缓存
* @param key
* @author 卓家进
* @Date 2015年3月10日下午4:12:45
*/
public void del(String key){
cacheManager.del(DataTypeUtils.stringToByte(key));
}
}</span></span>
这里另一个数据类型转换类,功能是String类型和byte类型之间的转换。这是在键值须要的转换。
Value还须要一个序列化的类来处理。
这个两个类就不贴代码了。
- 拦截器类
<span style="font-family:FangSong_GB2312;font-size:18px;"><span style="font-family:FangSong_GB2312;font-size:18px;">public class CacheInterceptor {
private Cache cache=new Cache();
@AroundInvoke
public Object cache(InvocationContext ctx) throws Exception{
System.out.println("进入拦截器");
String path = ctx.getTarget().getClass().getResource("").getPath();
XmlProperty xmlpro = XmlProperty.getInstance();
xmlpro.init(path);
cache.set("測试", "成功调用");
ctx.proceed();
System.out.println(cache.get("測试"));
String flag="调用成功";
return flag;
}
}</span></span>
这样,缓存client的开发以及须要和EJB结合的拦截器类就都能够了。须要用到缓存的项目仅仅要将jar包引入,让后在拦截器的注解上指明这里写的拦截器类就能够使用了。当然。上面仅仅是一个样例。缓存的Key值生成策略还没有考虑清楚,所以临时还不能用作缓存。
这个client也还须要做一些优化,优化将在下一篇博客讲!
Redis+EJB实现缓存(一)的更多相关文章
- Net分布式系统之五:C#使用Redis集群缓存
本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系统高并发查询,为了提供性能减 ...
- Spring Boot使用redis做数据缓存
1 添加redis支持 在pom.xml中添加 <dependency> <groupId>org.springframework.boot</groupId> & ...
- C#使用Redis集群缓存
C#使用Redis集群缓存 本文介绍系统缓存组件,采用NOSQL之Redis作为系统缓存层. 一.背景 系统考虑到高并发的使用场景.对于并发提交场景,通过上一章节介绍的RabbitMQ组件解决.对于系 ...
- 在AspNetCore 中 使用Redis实现分布式缓存
AspNetCore 使用Redis实现分布式缓存 上一篇讲到了,Core的内置缓存:IMemoryCache,以及缓存的基础概念.本篇会进行一些概念上的补充. 本篇我们记录的内容是怎么在Core中使 ...
- SpringMVC + MyBatis + Mysql + Redis(作为二级缓存) 配置
2016年03月03日 10:37:47 标签: mysql / redis / mybatis / spring mvc / spring 33805 项目环境: 在SpringMVC + MyBa ...
- redis哈希缓存数据表
redis哈希缓存数据表 REDIS HASH可以用来缓存数据表的数据,以后可以从REDIS内存数据库中读取数据. 从内存中取数,无疑是很快的. var FRedis: IRedisClient; F ...
- redis删除单个key和多个key,ssdb会落地导致重启redis无法清除缓存
redis删除单个key和多个key,ssdb会落地导致重启redis无法清除缓存,需要针对单个key进行删除 删除单个:del key 删除多个:redis-cli -a pass(密码) keys ...
- MySQL与Redis实现二级缓存
redis简介 Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库 Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化, ...
- Redis 集群缓存测试要点--关于 线上 token 失效 BUG 的总结
在测试账户系统过程中遇到了线上大面积用户登录态失效的严重问题,事后对于其原因及测试盲点做了一些总结记录以便以后查阅,总结分为以下7点,其中原理性的解释有些摘自网络. 1.账户系统token失效问题复盘 ...
随机推荐
- SPOJ - ADALIST,双端队列入门模板!
ADALIST - Ada and List 这道题时限6.5s,激动人心啊,好多人STL一顿乱写AC,哈哈,如果熟悉双端队列的话这道题其实是很水的. 题意:n个数的数列,然后接下来Q次操作,每次可以 ...
- 九度oj 题目1385:重建二叉树
题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7 ...
- 【Luogu】P2015二叉苹果树(DP,DFS)
题目链接 设f[i][j][k]表示给以i为根节点的子树分配j条可保留的树枝名额的时候,状态为k时能保留的最多苹果. k有三种情况. k=1:我只考虑子树的左叉,不考虑子树的右叉,此时子树能保留的最多 ...
- USACO Runaround Numbers
题目大意:问最近的比n大的循环数是多少 思路:第n遍暴力大法好 /*{ ID:a4298442 PROB:runround LANG:C++ } */ #include<iostream> ...
- 刷题总结——蚯蚓(NOIP2016DAY2T2)
题目: 题目背景 NOIP2016 提高组 Day2 T2 题目描述 本题中,我们将用符号
- HashMap构造函数有哪些
hashMap有4个构造函数: public HashMap(int initialCapacity, float loadFactor) public HashMap(int initialCapa ...
- 树状数组求第K大(From CLJ)
; <<log2[n];p;p>>=) if(a[ret+p]<=kth) kth-=a[ret+=p]; return ret;
- 【BZOJ3224】普通平衡树(splay)
题意: 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排 ...
- StringBuffer笔记
简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 Strin ...
- linux top %VSZ含义
https://blog.csdn.net/sinohenu/article/details/58216013 https://unix.stackexchange.com/questions/449 ...