zoukankan      html  css  js  c++  java
  • Spring 整合 Redis

    pom构建:

    <dependency>  
            <groupId>org.springframework.data</groupId>  
            <artifactId>spring-data-redis</artifactId>  
            <version>1.6.0.RELEASE</version>  
        </dependency>  
        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-test</artifactId>  
            <version>3.1.2.RELEASE</version>  
            <scope>test</scope>  
        </dependency>  
          
        <dependency>  
            <groupId>redis.clients</groupId>  
            <artifactId>jedis</artifactId>  
            <version>2.9.0</version>  
        </dependency>  
          
         <dependency>  
            <groupId>junit</groupId>  
            <artifactId>junit</artifactId>  
            <version>4.8.2</version>  
            <scope>test</scope>  
        </dependency>  

    spring配置文件(applicationContext.xml):

    	<context:property-placeholder location="classpath:redis.properties" />  
    	<!-- redis config start -->
    	<!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->
    	<cache:annotation-driven cache-manager="cacheManager" />
    
    
    	<!-- 配置JedisPoolConfig实例 -->
    	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    		<property name="maxTotal" value="${redis.maxTotal}" />
    		<property name="maxIdle" value="${redis.maxIdle}" />
    		<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
    		<property name="testOnBorrow" value="${redis.testOnBorrow}" />
    		<property name="testOnReturn" value="${redis.testOnReturn}" />
    		<!-- <property name="testWhileIdle" value="true"/> -->
    	</bean>
    
    
    	<!-- 配置JedisConnectionFactory -->
    	<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="jedisPoolConfig" p:timeout="${redis.timeout}" />
    
    
    	<!-- 配置RedisTemplate -->
    	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
    		<property name="connectionFactory" ref="JedisConnectionFactory" />
    	</bean>
    
    	<!-- spring自己的缓存管理器,这里定义了缓存位置名称 ,即注解中的value -->
    	<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    		<property name="caches">
    			<set>
    				<!-- 这里可以配置多个redis -->
    				<!-- <bean class="com.cn.util.RedisCache"> <property name="redisTemplate" 
    					ref="redisTemplate" /> <property name="name" value="default"/> </bean> -->
    				<bean class="com.github.util.RedisCache">
    					<property name="redisTemplate" ref="redisTemplate" />
    					<property name="name" value="common" />
    					<!-- common名称要在类或方法的注解中使用 -->
    				</bean>
    			</set>
    		</property>
    	</bean>
    	<!-- redis config end -->

    开启Spring采用CGLIB代理

    <!-- 配置使Spring采用CGLIB代理 -->
    <aop:aspectj-autoproxy proxy-target-class="true" />


    redis.properties:

    # Redis settings
    redis.host=192.168.1.39
    redis.port=6379
    redis.pass=jay
    redis.timeout=0
    
    redis.maxIdle=300
    redis.maxTotal=50
    redis.maxWaitMillis=1000
    redis.testOnBorrow=true
    redis.testOnReturn=true

    Java代码:

    自己实现的缓存类 RedisCache

    package com.github.util;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    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;
    
    	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;
    	}
    
    	@Override
    	public String getName() {
    		return this.name;
    	}
    
    	@Override
    	public Object getNativeCache() {
    		return this.redisTemplate;
    	}
    
    	@Override
    	public ValueWrapper get(Object key) {
    		System.out.println("get key");
    		final String keyf = key.toString();
    		Object object = null;
    		object = redisTemplate.execute(new RedisCallback<Object>() {
    			public Object doInRedis(RedisConnection connection)
    					throws DataAccessException {
    				byte[] key = keyf.getBytes();
    				byte[] value = connection.get(key);
    				if (value == null) {
    					return null;
    				}
    				return toObject(value);
    			}
    		});
    		return (object != null ? new SimpleValueWrapper(object) : null);
    	}
    
    	@Override
    	public void put(Object key, Object value) {
    		System.out.println("put key");
    		final String keyf = key.toString();
    		final Object valuef = value;
    		final long liveTime = 10 * 6;		//86400一天
    		redisTemplate.execute(new RedisCallback<Long>() {
    			public Long doInRedis(RedisConnection connection)
    					throws DataAccessException {
    				byte[] keyb = keyf.getBytes();
    				byte[] valueb = toByteArray(valuef);
    				connection.set(keyb, valueb);
    				if (liveTime > 0) {
    					connection.expire(keyb, liveTime);
    				}
    				return 1L;
    			}
    		});
    	}
    
    	private byte[] toByteArray(Object obj) {
    		byte[] bytes = null;
    		ByteArrayOutputStream bos = new ByteArrayOutputStream();
    		try {
    			ObjectOutputStream oos = new ObjectOutputStream(bos);
    			oos.writeObject(obj);
    			oos.flush();
    			bytes = bos.toByteArray();
    			oos.close();
    			bos.close();
    		} catch (IOException ex) {
    			ex.printStackTrace();
    		}
    		return bytes;
    	}
    
    	private Object toObject(byte[] bytes) {
    		Object obj = null;
    		try {
    			ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
    			ObjectInputStream ois = new ObjectInputStream(bis);
    			obj = ois.readObject();
    			ois.close();
    			bis.close();
    		} catch (IOException ex) {
    			ex.printStackTrace();
    		} catch (ClassNotFoundException ex) {
    			ex.printStackTrace();
    		}
    		return obj;
    	}
    
    	@Override
    	public void evict(Object key) {
    		System.out.println("del key");
    		final String keyf = key.toString();
    		redisTemplate.execute(new RedisCallback<Long>() {
    			public Long doInRedis(RedisConnection connection)
    					throws DataAccessException {
    				return connection.del(keyf.getBytes());
    			}
    		});
    	}
    
    	@Override
    	public void clear() {
    		System.out.println("clear key");
    		redisTemplate.execute(new RedisCallback<String>() {
    			public String doInRedis(RedisConnection connection)
    					throws DataAccessException {
    				connection.flushDb();
    				return "ok";
    			}
    		});
    	}
    
    	@Override
    	public <T> T get(Object key, Class<T> type) {
    		return null;
    	}
    
    	@Override
    	public ValueWrapper putIfAbsent(Object key, Object value) {
    		return null;
    	}
    
    }


    注意:

    spring配置文件中的

    <bean class="com.github.util.RedisCache">
    <property name="redisTemplate" ref="redisTemplate" />
    <property name="name" value="common" />
    <!-- common名称要在类或方法的注解中使用 -->
    </bean>


    name 的value 可以自定义 。后面方法注解的value要和这个对应


    对Redis不懂的看这篇文章.


    这里配置就完成了。可以直接在service方法上面开启注解:

    有4个注解@Cacheable,@CachePut , @CacheEvict,@CacheConfig

    @Cacheable、@CachePut、@CacheEvict 注释介绍

    @Cacheable 作用和配置方法
    @Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
    @Cacheable 主要的参数
    value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:这里和上面的name 的value对应,楼主这里写的是common
    @Cacheable(value=”mycache”) 或者
    @Cacheable(value={”cache1”,”cache2”}
    key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
    @Cacheable(value=”testcache”,key=”#userName”)
    condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:
    @Cacheable(value=”testcache”,condition=”#userName.length()>2”)
    ------------------------------------------------------------
    --////////////////////////////////////////////////////////////////////////////////


    @CachePut 作用和配置方法
    @CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
    @CachePut 主要的参数
    value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:
    @Cacheable(value=”mycache”) 或者
    @Cacheable(value={”cache1”,”cache2”}
    key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
    @Cacheable(value=”testcache”,key=”#userName”)
    condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存例如:
    @Cacheable(value=”testcache”,condition=”#userName.length()>2”)

    @CachePut 不同的是不管有没有缓存,都会调用方法.使用于 数据库的插入
    //////////////////////////////////////////////////////


    @CacheEvict 作用和配置方法
    @CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
    @CacheEvict 主要的参数
    value 缓存的名称,在 spring 配置文件中定义,必须指定至少一个例如:
    @CachEvict(value=”mycache”) 或者
    @CachEvict(value={”cache1”,”cache2”}
    key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合例如:
    @CachEvict(value=”testcache”,key=”#userName”)
    condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存例如:
    @CachEvict(value=”testcache”,
    condition=”#userName.length()>2”)
    allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存例如:
    @CachEvict(value=”testcache”,allEntries=true)
    beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存例如:
    @CachEvict(value=”testcache”,beforeInvocation=true)


    额外补充

    知道你们注意到一个问题没有,就是所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了,
    所以,有了@CacheConfig这个配置,@CacheConfigis a class-level annotation that allows to share the cache names,不过不用担心,如果你在你的方法写别的名字,那么依然以方法的名字为准。
    注释在类上面
    @CacheConfig(cacheNames = "common")

  • 相关阅读:
    problems_mysql
    skills_mysql
    knowledge_mysql
    knowledge_impala
    oozie的常见错误
    problems_kafka
    problems_flume
    kafka在zookeeper默认使用/为根目录,将/更换为/kafka
    java学习笔记总略
    大公司怎么开发和部署前端代码——作者:张云龙[知乎兴趣转载]
  • 原文地址:https://www.cnblogs.com/zhousiwei/p/10625806.html
Copyright © 2011-2022 走看看