<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>1.0.1.RELEASE</version> <exclusions> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> <exclusion> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> </exclusion> </exclusions> </dependency>
其中exclusion了两个包,原因是与项目里其它包冲突。
bean配置如下,可在web.xml里配置加载bean文件:
<bean id="redisCacheManager" class="com.cr.common.cache.base.RedisCacheManger"> <property name="pool" ref="shardedJedisPool"/> </bean> <!-- jedis 连接池配置--> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxActive" value="${redis.pool.maxActive}" /> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <property name="maxWait" value="${redis.pool.maxWait}" /> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> </bean> <!-- jedis 多个服务器配置--> <bean id="jedisShardInfo1" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis2.ip}" /> <constructor-arg index="1" value="${redis.port}" type="int" /> </bean> <bean id="jedisShardInfo2" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis.ip}" /> <constructor-arg index="1" value="${redis.port}" type="int" /> </bean> <bean id="shardedJedisPool" class="redis.clients.jedis.ShardedJedisPool"> <constructor-arg index="0" ref="jedisPoolConfig" /> <constructor-arg index="1"> <list> <ref bean="jedisShardInfo1" /> <ref bean="jedisShardInfo2"/> </list> </constructor-arg> </bean> <bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > <property name="hostName" value="${redis.ip}" /> <property name="port" value="${redis.port}" /> <property name="poolConfig" ref="jedisPoolConfig" /> <!--<property name="shardInfo" ref="shardedJedisPool"></property>--> </bean> <context:property-placeholder location="/WEB-INF/spring/SystemContext.properties"/> <context:component-scan base-package="org.springframework.data.redis.samples"/>
属性文件内容如下:
redis.ip=192.168.1.110 redis2.ip=192.168.1.112 #Port redis.port=6379 #最大分配的对象数 redis.pool.maxActive=1024 #最大能够保持idel状态的对象数 redis.pool.maxIdle=200 #当池内没有返回对象时,最大等待时间 redis.pool.maxWait=1000 #当调用borrow Object方法时,是否进行有效性检查 redis.pool.testOnBorrow=true #当调用return Object方法时,是否进行有效性检查 redis.pool.testOnReturn=true
缓存管理接口:
public interface RedisCache { public <T> T getRedisCacheInfo(String key); public <T> boolean setRedisCacheInfo(String key, T value); }
缓存管理实现:
public class RedisCacheManger implements RedisCache { private ShardedJedisPool pool ; private Logger log = Logger.getLogger(RedisCacheManger.class); public ShardedJedisPool getPool() { return pool; } public void setPool(ShardedJedisPool pool) { this.pool = pool; } public <T> T getRedisCacheInfo(String key) { try { log.info("get from redisCache :"+key); System.out.println("get from rediscache"); ShardedJedis jedis = pool.getResource(); pool.returnResource(jedis); return (T)jedis.get(key); } catch (Exception e) { e.printStackTrace(); } return null; } public <T> boolean setRedisCacheInfo(String key, T value) { try { log.info("add to redisCache :"+key); System.out.println("add to rediscache"); ShardedJedis jedis = pool.getResource(); jedis.set(key, (String)value); pool.returnResource(jedis); return true; } catch (Exception e) { e.printStackTrace(); } return false; } public static void main(String[] args) { new RedisCacheManger().setRedisCacheInfo("12345", "asdfg"); } }
缓存切面注解:
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface NeedRedisCached {}
缓存切面处理类:
@Aspect public class RedisCacheAspect implements Ordered { private static Logger log = Logger.getLogger(RedisCacheAspect.class); private RedisCache redisCacheManager; private int orderValue = 3; public RedisCache getRedisCacheManager() { return redisCacheManager; } public void setRedisCacheManager(RedisCache redisCacheManager) { this.redisCacheManager = redisCacheManager; } @Pointcut("@annotation(com.jd.bi.odp.common.cache.core.NeedRedisCached)") public void needRedisCached() { } @Around("needRedisCached() && args(filter,..)") public Object aroundInvoke(ProceedingJoinPoint pjp, QueryFilter filter) throws Throwable { log.info("enter aroundInvoke!!!"); if (filter.getValue() == null) { return null; } boolean cacheEnabled = CommonUtil.parseBoolean(HBaseConfig.getProperty("redisCache.enabled"), false); if (cacheEnabled) { String md5key = MD5Util.getMD5(filter.getValue().toString()); Object value = redisCacheManager.getRedisCacheInfo(md5key); boolean flag = false; if (null != value) { JSONObject json = new JSONObject(value.toString()); return json; } else if ("null".equals(value)) { return null; } else { //执行hbase查询 value = pjp.proceed(); if(null!=value){//此处根据业务逻辑判断不缓存的条件 } else{ flag = redisCacheManager.setRedisCacheInfo(md5key, value.toString()); if(flag) log.info("add a cache success by key: "+md5key); else log.warn("add a cache failure by key: "+md5key); } } return value; } } else {// 执行hbase查询 return pjp.proceed(); } } @Override public int getOrder() { return orderValue; } public int getOrderValue() { return orderValue; } public void setOrderValue(int orderValue) { this.orderValue = orderValue; } }
缓存存在直接返回,不存在的话执行数据源查询,此处是hbase查询,并设置缓存。
切面配置:
<!-- redis缓存运行切面 --> <bean id="RedisCacheAspect" class="com.cr.common.cache.core.RedisCacheAspect"> <property name="orderValue" value="3" /> <property name="redisCacheManager" ref="redisCacheManager"/> </bean> <!-- 切面申明配置--> <aop:aspectj-autoproxy> <aop:include name="RedisCacheAspect" /> </aop:aspectj-autoproxy>
此时,前端web页面用户的访问触发的action如果满足条件,则会进入切面方法处理,完成redis缓存的使用。