spring--springCache原理和扩展性

###1.springcache原理 springCache的关键原理就是spring aop,通过sop的前置通知/后置通知/返回通知,实现了方法在调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。
原理理解:客户端调用spring中的方法时(假设方法名为A),spring cache利用spring aop动态代理技术,给客户端的不是方法A,而是一个动态生成的类。这个时候客户端在调用方法A的时候,实际上调用的是动态类生成的方法(假设B),这个时候动态类可以整体的控制实际方法A的入参和返回值,即将其结果缓存起来等。
###2.springcache扩展性
springcache不支持高并发可用性,也不具备持久化数据能力(因此,我引入了spring集成redis这篇文章),这个时候,我们就需要自定义缓存方案。
1.我们需要提供一个CacheManager接口的实现。这个接口会告诉spring有哪些cache实例,spring会根据cache的名字查找cache的实例。
2.实现Cache接口,cache接口负责实际的缓存逻辑,例如增加对象/更新对象、删除对象等。
3.利用Cache接口,我们可以快速的对接第三方缓存系统
####基础类

/**
 * 基本类
 */
public class Account {
	private int id;
	private String name;
	private String password;
}

####业务类

package com.test.spring.cacheCommon;

import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;

/**
 * 业务类 
 */
public class MyAccountService {
	/**
	 * key的组合使用
	 */
	@Cacheable(value="accountCache",key="#name.concat(#password)")
	//根据key获取对象值
	public Account getAccountByName(String name,String password){
		Account result = getFromDB(name,password);
		return result;
	}
	
	/**
	 * 
	 * @CachePut使用
	 * 
	 */
	@CachePut(value="accountCache",key="#account.getName()")
	 public Account updateAccount(Account account) { 
	   return updateDB(account); 
	 }
	
	//更新账号信息
	private Account updateDB(Account account) { 
	   System.out.println("real updating db..."+account.getName()); 
	   return account; 
	}
	
	//数据库查询账号信息
	private Account getFromDB(String name,String password) {
		System.out.println("去数据库查询");
		return new Account(name,password);
	}
}

####MyCache

package com.test.spring.cacheCommon;

import java.util.HashMap;
import java.util.Map;

import org.springframework.cache.Cache;
import org.springframework.cache.support.SimpleValueWrapper;

public class MyCache implements Cache{
	
	//自定义私有参数
	private String name;

	private Map<String, Object> store = new HashMap<String, Object>();
	
	//无参构造器
	public MyCache() {
		
	}
	
	//有参构造器
	public MyCache(String name) {
		this.name = name;
	}
	
	@Override
	public String getName() {
		return name;
	}

	@Override
	public Object getNativeCache() {
		return store;
	}

	@Override
	public ValueWrapper get(Object key) {
		
	     ValueWrapper result = null; 
	     Object thevalue = store.get(key); 
	     if(thevalue!=null) { 
	       result = new SimpleValueWrapper(thevalue); 
	     } 
		
		return result;
	}

	@Override
	public <T> T get(Object key, Class<T> type) {
		return type.cast(store.get(key));
	}

	@Override
	public void put(Object key, Object value) {
		store.put((String)key, value);
	}

	@Override
	public ValueWrapper putIfAbsent(Object key, Object value) {
        put(key, value);  
        return new SimpleValueWrapper(value); 
	}

	@Override
	public void evict(Object key) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void clear() {
		store.clear();
	}

	public void setName(String name) {
		this.name = name;
	}	

}

####缓存管理器类

package com.test.spring.cacheCommon;

import java.util.Collection;

import org.springframework.cache.support.AbstractCacheManager;

/**
 * 该类继承了spring的AbstractCacheManager
 * 仅仅管理MyCache
 *
 */
public class MyCacheManager extends AbstractCacheManager{

	private Collection<? extends MyCache> caches;
	
	@Override
	protected Collection<? extends MyCache> loadCaches() {
		// TODO Auto-generated method stub
		return this.caches;
	}


	public void setCaches(Collection<? extends MyCache> caches) {
		this.caches = caches;
	}
	

}

####测试类

package com.test.spring.cacheCommon;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 测试类
 *
 */
public class Main {
	
	public static void main(String[] args) {
		
		ApplicationContext ctx = new ClassPathXmlApplicationContext("springCacheCommon.xml");
		
		MyAccountService myAccountService = (MyAccountService) ctx.getBean("myAccountService");
		
		//第一次查询,去数据库查询
		myAccountService.getAccountByName("张三","123456");
		//第二次查询,从缓存中查询
		myAccountService.getAccountByName("张三","123456");
		
		//
		Account account = myAccountService.getAccountByName("张三", "123456");
		myAccountService.updateAccount(account);
		
		//第三次查询,从数据库查询
		myAccountService.getAccountByName("张三","123456");
		
		//第四次查询,从数据库查询
		myAccountService.getAccountByName("张三","654321");
		//第五次查询,从缓存中查询
		myAccountService.getAccountByName("张三","654321");
	}

}

####结果

去数据库查询
real updating db...张三
去数据库查询

转载于:https://my.oschina.net/u/2312022/blog/742632

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值