spring 配置 cache 缓存使用 ConcurrentMap EhCache Redis

spring cache 总结

    作用:  保证数据时效性的前提下, 提高查询效率; 减少查询数据库的次数, 减轻数据库压力;

    原理 基于Proxy/AspectJ动态代理技术的AOP思想(面向切面编程), 在不改变目标方法的前提下在其切面进行缓存的增删改查(在服务方法执行前查询缓存, 在服务方法执行后添加缓存, 或者清除缓存);

    用法: 

        1. spring cache实现有基于XML/注解实现AOP;

        2. CacheManager负责对缓存的增删改查, CacheManager的缓存的介质可配置, 如: ConcurrentMap/EhCache/Redis等;

spring cache 实例

1. 导入jar包


	org.springframework.data
	spring-data-redis
	1.6.2.RELEASE


	redis.clients
	jedis
	2.9.0




	com.fasterxml.jackson.core
	jackson-core
	2.9.2



	com.fasterxml.jackson.core
	jackson-databind
	2.9.2



	com.fasterxml.jackson.core
	jackson-annotations
	2.9.2




	commons-logging
	commons-logging
	1.2



	log4j
	log4j
	1.2.17
2. 配置spring-cache.xml


    
    

    
    
        
            
                
                
            
        
    
	
    
    
   
3. 使用及测试
package com.csdn.learn.springcache;

import com.csdn.learn.annocache.Account;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;

/**
 * 使用@Cacheable, @CachePut, @CacheEvict, @CacheConfig spring通过AOP对方法进行缓存管理
 * @author liudong
 * @date 2018-04-27
 */
public class AccountService {

    /**
     * 使用了一个缓存名叫 accountCache
     * key condition ,前面的 # 号代表这是一个 SpEL 表达式
     * @param userName
     * @return
     */
    @Cacheable(value = "accountCache", key = "#userName", condition = "#userName.length() <= 4")
    public Account getAccountByName(String userName) {
        // 方法内部实现不考虑缓存逻辑,直接实现业务
        System.out.println("real querying db..." + acctName + "+" + password);
        return new Account(acctName);
    }

    /**
     * 更新 accountCache 缓存
     * @param account dd
     */
    @CachePut(value = "accountCache", key = "#account.getName()")
    public void updateAccount(Account account) {
        System.out.println("real update db..." + account.getName());
    }

    /**
     * reload 清空 accountCache 缓存
     */
    @CacheEvict(value = "accountCache", allEntries = true)
    public void reload() {
    }

}
package com.csdn.learn.annocache;

import java.io.Serializable;

/**
 * 首先定义一个实体类:账号类,具备基本的 id 和 name 属性,且具备 getter 和 setter 方法
 * @author liudong
 * @date 2018-04-27
 */
public class Account implements Serializable {
    private static final long serialVersionUID = 1L;

    private int id;
    private String name;
    private String password;

    public Account() {
        super();
    }

    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public Account(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}
package com.csdn.learn.rediscacheanno;

import com.csdn.learn.annocache.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.RedisTemplate;

public class Main {

    public static void main(String[] args) {
        // 加载 spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-cache.xml");

        AccountService s = (AccountService) context.getBean("accountServiceBean");
		
        // 第一次查询,应该走数据库
        System.out.print("first query...");
        s.getAccountByName("somebody");
        // 第二次查询,应该不查数据库,直接返回缓存的值
        System.out.print("second query...");
        s.getAccountByName("somebody");
        System.out.println();

	// TODO 自行测试@CachePut及@CacheEvict
		
	// 测试redisTemplate
	RedisTemplate redisTemplate = (RedisTemplate) context.getBean("redisTemplate");
	// redis中存取字符串
        redisTemplate.opsForValue().set("redis2", "ceshiRedis222");
        System.out.println(redisTemplate.opsForValue().get("redis2"));
	// redis中存取实体类
        redisTemplate.opsForValue().set("account", new Account("ceshi 123"));
        System.out.println(redisTemplate.opsForValue().get("account"));
    }
}

内存式普通缓存使用大功告成, 由于spring整合Redis的做缓存时配置最难搞定, 所以仅介绍配置

方式一. spring整合Redis的xml配置
#============================#
#==== Redis settings ====#
#============================#
#redis 服务器 IP
redis.host=127.0.0.1
#redis 服务器端口
redis.port=6379
#redis 密码
redis.pass=
#redis 支持16个数据库(相当于不同用户)可以使不同的应用程序数据彼此分开同时又存储在相同的实例上
redis.dbIndex=1
#redis 缓存数据过期时间单位秒
redis.expiration=3000
#控制一个 pool 最多有多少个状态为 idle 的jedis实例
redis.maxIdle=300
#控制一个 pool 可分配多少个jedis实例
redis.maxActive=600
#当borrow一个jedis实例时,最大的等待时间,如果超过等待时间,则直接抛出JedisConnectionException;
redis.maxWait=1000
#在borrow一个jedis实例时,是否提前进行alidate操作;如果为true,则得到的jedis实例均是可用的;
redis.testOnBorrow=true


    
    
    
    
    
        
        
        
        
    

    
    
        
        
        
        
        
    

    
    
    
    
    
    
    
    
    
    
    
    

    
    
        
        
    

    
    
    
    
    
    
    
方式二. spring整合Redis的纯注解配置



    
    
    
    
        
        
        
    
    
    

    
    
    
    
package com.csdn.learn.rediscacheanno;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {

    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
//        cacheManager.setDefaultExpiration(3600);//默认缓存一小时
        return cacheManager;
    }

    /**
     * redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 使用Jackson2JsonRedisSerialize 替换默认序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        // 设置value的序列化规则和 key的序列化规则
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
最后, SpringBoot整合Redis做缓存Cache技术配置非常简单, 可以试着玩一玩


你可能感兴趣的:(spring 配置 cache 缓存使用 ConcurrentMap EhCache Redis)