spring缓存机制-自定义缓存(六)

spring是一个轻量级开源框架,以IoC(Inverse of Control:控制反转)和AOP(Aspect Oriented Programming:面向切面编程)为内核,
兼具功能强大的的原生展现层spring mvc,原生持久层spring jdbc和原生业务层等技术,并且以海纳百川的胸怀整合了开源世界里众多
著名的第三方框架和类库,已经逐渐成为世界上使用最多的JavaEE企业级应用开源框架.
现在我们已经学会了如何使用开箱即用的spring cache,他也基本能够满足一般的需求,但是当你的用户量上去或者性能跟不上的时候,
你就需要自定义你的缓存方案了.如何利用spring cache提供的扩展点实现我们自己的缓存,前提是在不改原来已有代码的情况下进行扩展.

1.首先,我们需要提供一个CacheManager接口的实现,这个接口告诉spring有哪些cache实例,spring会根据cache的名字查找cache的实例.

<span style="font-size:12px;">package com.ilucky.spring.cache.ilucky;

import java.util.Collection;

import org.springframework.cache.support.AbstractCacheManager;

/**
 * @author IluckySi
 * @date 20140615
 */
public class IluckyCacheManager extends AbstractCacheManager {

	private Collection<? extends IluckyCache> caches;

	/**
	 * JVM加载spring配置文件时, 通过set方法注入本类的参数.
	 * @param caches
	 */
	public void setCaches(Collection<? extends IluckyCache> caches) {
		this.caches = caches;
	}

	@Override
	public Collection<? extends IluckyCache> loadCaches() {
		return caches;
	}
}
</span>

2.另外,还需要实现Cache接口,Cache接口负责实际的缓存逻辑,例如增加键值对、存储、查询和清空等.

<span style="font-size:12px;">package com.ilucky.spring.cache.ilucky;

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

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

import com.ilucky.spring.cache.model.User;

/**
 * @author IluckySi
 * @date 20140615
 */
public class IluckyCache implements Cache {
	
	private String name;
	
	private Map<String, User> store = new HashMap<String, User>();
	
	public IluckyCache() {
		
	}
	
	public IluckyCache(String name) {
		this.name = name;
	}
	
	@Override
	public String getName() {
		return name;
	}

	/**
	 * JVM加载spring配置文件时, 通过set方法注入本类的参数.
	 * @param userDao
	 */
	public void setName(String name) { 
	     this.name = name; 
	} 

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

	@Override
	public ValueWrapper get(Object key) {
		ValueWrapper result = null;
		User user = store.get(key);
		if(user != null) {
			System.out.println("缓存中存在key=" + key + "的User!");
		    result = new SimpleValueWrapper(user); 
		} else {
			System.out.println("缓存中不存在key=" + key + "的Uesr!");
		}
		return result;
	}

	@Override
	public void put(Object key, Object value) {
		 User user = (User)value; 
	     store.put((String)key, user); 
	     System.out.println("向缓存中成功加入一条数据: " + user);
	}

	@Override
	public void evict(Object key) {
	}

	@Override
	public void clear() {
	}
}
</span>

3.创建spring配置文件,配置自定义的缓存管理器和bean之间的依赖关系,直接看代码spring-cahce.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="   
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
                http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd">


	<!-- 应用spring cache注解功能  -->
	<cache:annotation-driven />

 	<!-- 创建spring cache bean -->
	<bean id="cacheManager" class="com.ilucky.spring.cache.ilucky.IluckyCacheManager">
		<property name="caches">
			<set>
				<!--配置自定义缓存 -->
				<bean class="com.ilucky.spring.cache.ilucky.IluckyCache" p:name="data" />
			</set>
		</property>
	</bean>

	<!-- 创建User Dao bean -->
	<bean id="userDao" class="com.ilucky.spring.cache.dao.impl.UserDaoImpl" ></bean>

	<!-- 创建User Service bean -->
	<bean id="userService" class="com.ilucky.spring.cache.service.impl.UserServiceImpl" >
		<property name="userDao" >
			<ref bean="userDao"></ref>
		 </property>
	</bean> 
</beans>  

4.最后通过测试类测试spring缓存机制是否生效,直接看代码MainTest.

<span style="font-size:12px;">package com.ilucky.spring.cache;

import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ilucky.spring.cache.ilucky.IluckyCache;
import com.ilucky.spring.cache.ilucky.IluckyCacheManager;
import com.ilucky.spring.cache.model.User;
import com.ilucky.spring.cache.service.UserService;

/**
 * @author IluckySi
 * @date 20140615
 * 测试spring缓存机制是否生效.
 */
public class MainTest {

	public static void main(String[] args) {
		
		//加载ClassPath路径下的spring配置文件, 并获取service bean. 注意: 我们可以获取spring配置文件中配置的任何bean.
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-cache.xml");  
		UserService userService = context.getBean("userService", UserService.class); 
		System.out.println("service bean: " + userService);
		IluckyCacheManager cacheManager = context.getBean("cacheManager", IluckyCacheManager.class);
		System.out.println("service bean: " + cacheManager);
		System.out.println("--------------bean初始化完成---------------");
		
		//验证id.length() < =5的数据不会放入缓存中.
		userService.add(new User("1", "Ilucky", "Ilucky1"));
		userService.find("1");
		userService.add(new User("111111", "Ilucky", "Ilucky111111"));
		userService.find("111111");
		
		//验证
		userService.find("111111");
		
		//遍历缓存(两种方案).
		System.out.println("---------------第一种方案获取缓存---------------");
		Collection<String> cacheNames = cacheManager.getCacheNames();
		Iterator<String> iterator = cacheNames.iterator();
		while(iterator.hasNext()) {
			String cacheName = iterator.next();
			System.out.println("缓存名称: " + cacheName);
			IluckyCache iluckyCache = (IluckyCache)cacheManager.getCache(cacheName);
			Map<String, User> map = (Map<String, User>) iluckyCache.getNativeCache();
			for(Entry<String, User> entry : map.entrySet()) {
				System.out.println("--------" +entry.getValue());
			}
		}
		System.out.println("---------------第二种方案获取缓存---------------");
		Collection<? extends IluckyCache> caches = cacheManager.loadCaches();
		Iterator<? extends IluckyCache> it = caches.iterator();
		while(it.hasNext()) {
			IluckyCache iluckyCache = it.next();
			System.out.println("缓存名称: " + iluckyCache.getName());
			Map<String, User> map = (Map<String, User>) iluckyCache.getNativeCache();
			for(Entry<String, User> entry : map.entrySet()) {
				System.out.println("--------" +entry.getValue());
			}
		}
	}
}
/**
spring缓存分为两种:方法和数据,如果方法被清除了,需要重新从数据库获取数据放入缓存,另外只有方法加入了缓存才可以获取缓存中的数据.
输出结果:
service bean: com.ilucky.spring.cache.service.impl.UserServiceImpl@92dcdb
service bean: com.ilucky.spring.cache.ilucky.IluckyCacheManager@1e1be92
--------------bean初始化完成---------------
UserService: method- add(User user)
UserDao method- add(User user)
UserService: method-find(String id)
UserDao method- find(String id)
UserService: method- add(User user)
UserDao method- add(User user)
缓存中不存在key=111111的Uesr!
UserService: method-find(String id)
UserDao method- find(String id)
向缓存中成功加入一条数据: 111111-Ilucky-Ilucky111111
缓存中存在key=111111的User!
---------------第一种方案获取缓存---------------
缓存名称: data
--------111111-Ilucky-Ilucky111111
---------------第二种方案获取缓存---------------
缓存名称: data
--------111111-Ilucky-Ilucky111111

帮助分析:
执行第一个userService.find("111111")方法时输出如下:
缓存中不存在key=111111的Uesr!
UserService: method-find(String id)
UserDao method- find(String id)
向缓存中成功加入一条数据: 111111-Ilucky-Ilucky111111
即:在执行find方法前,通过AOP机制首先从缓存中获取数据,如果获取不到,再从数据库获取,
最后再通过AOP机制将从数据库获取的数据放入缓存中.

执行第二个userService.find("111111")方法时输出如下:
缓存中存在key=111111的User!
即:在执行find方法前,通过AOP机制首先从缓存中获取数据,如果有直接返回.
*/
</span>
注意:spring缓存分为两种:方法和数据,如果方法被清除了,需要重新从数据库获取数据放入缓存,另外只有方法加入了缓存才可以获取缓存中的数据.
点击链接下载源码!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值