`
tom_seed
  • 浏览: 321790 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring使用注解式@Cache集成xmemcache

 
阅读更多

在《Spring集成memcache(二)xmemcache》的基础之上扩展支持注解形式,使开发更加简洁。

参考资料如下:

http://zj0121.iteye.com/blog/1852270

 

需要注意的是扩展支持注解需要Spring AOP的支持,需要导入相应的jar包:

1.aopalliance-1.0.jar

2.aopalliance-alpha1.jar

3.slf4j-api-1.7.5.jar

其中slf4j-api-1.7.5.jar提供的是日志的接口规范,如果工程目录下使用的是log4j,则slf4j-api-1.7.5.jar会绑定调用log4j.jar。

具体说明可以访问http://blog.csdn.net/tengdazhang770960436/article/details/18006127

 

从头开始进行配置,步骤如下:

1.添加xmemcache.jar包至工程中;

  • aopalliance-1.0.jar
  • aopalliance-alpha1.jar
  • slf4j-api-1.7.5.jar
  • xmemcached-1.3.8.jar

2.在web.xml文件中添加配置

 

<context-param>  
    <param-name>contextConfigLocation</param-name>  
    <param-value>  
        /WEB-INF/conf/spring/*-beans.xml  
    </param-value>  
</context-param>

 

 

3.在属性文件中添加如下配置:

 

#memcache配置  
memcache.ip=127.0.0.1  
memcache.port=11211  
memcache.pool.size=5  

 

 

4.在/WEB-INF/conf/spring/目录下添加配置文件memcache-beans.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:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
        http://www.springframework.org/schema/cache  
        http://www.springframework.org/schema/cache/spring-cache-3.2.xsd"
	default-autowire="byName">

	<bean id="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">
		<constructor-arg>
			<list>
				<bean class="java.net.InetSocketAddress">
					<constructor-arg value="${memcache.ip}" />
					<constructor-arg value="${memcache.port}" />
				</bean>
			</list>
		</constructor-arg>
		<property name="connectionPoolSize" value="${memcache.pool.size}" />
		<property name="commandFactory">
			<bean class="net.rubyeye.xmemcached.command.BinaryCommandFactory" />
		</property>
		<property name="transcoder">
			<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
		</property>
	</bean>

	<bean id="memcachedClient" factory-bean="memcachedClientBuilder"
		factory-method="build" destroy-method="shutdown" />
		
	<bean id="cacheManager" class="com.iaccount.framework.cache.memcache.MemcachedCacheManager">
		<property name="memcachedClient" ref="memcachedClient" />
		<property name="configMap">
			<map>
				<!-- key:@Cacheable、@CachePut、@CacheEvict等的value属性。value:缓存过期时间(单位:秒),默认值:0 -->
				<entry key="defaultCache" value="0" /><!-- 默认缓存区 不过期 -->
				<entry key="inTimeCache" value="3600" /><!-- 实时缓存区 一小时过期 -->
			</map>
		</property>
	</bean>

	<cache:annotation-driven cache-manager="cacheManager" />
</beans>

 

 

5.参考了EHCacheCacheManager的源码,写了一个基于XMemcached的MemcachedCacheManager

a.memcache缓存连接类 MemCache.java  

 

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.exception.MemcachedException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MemCache {
	
	private static Logger log = LoggerFactory.getLogger(MemCache.class);

	private Set<String> keySet = new HashSet<String>();
	private final String name;
	private final int expire;
	private final MemcachedClient memcachedClient;

	public MemCache(String name, int expire, MemcachedClient memcachedClient) {
		this.name = name;
		this.expire = expire;
		this.memcachedClient = memcachedClient;
	}

	public Object get(String key) {
		Object value = null;
		try {
			key = this.getKey(key);
			value = memcachedClient.get(key);
		} catch (TimeoutException e) {
			log.warn("获取 Memcached 缓存超时", e);
		} catch (InterruptedException e) {
			log.warn("获取 Memcached 缓存被中断", e);
		} catch (MemcachedException e) {
			log.warn("获取 Memcached 缓存错误", e);
		}
		return value;
	}

	public void put(String key, Object value) {
		if (value == null)
			return;
		try{
			key = this.getKey(key);
			memcachedClient.setWithNoReply(key, expire, value);
			keySet.add(key);
		}catch (InterruptedException e){
			log.warn("更新 Memcached 缓存被中断", e);
		}catch (MemcachedException e){
			log.warn("更新 Memcached 缓存错误", e);
		}
	}

	public void clear(){
		for (String key : keySet){
			try{
				memcachedClient.deleteWithNoReply(this.getKey(key));
			}catch (InterruptedException e){
				log.warn("删除 Memcached 缓存被中断", e);
			}catch (MemcachedException e){
				log.warn("删除 Memcached 缓存错误", e);
			}
		}
	}

	public void delete(String key){
		try{
			key = this.getKey(key);
			memcachedClient.deleteWithNoReply(key);
		}catch (InterruptedException e){
			log.warn("删除 Memcached 缓存被中断", e);
		}catch (MemcachedException e){
			log.warn("删除 Memcached 缓存错误", e);
		}
	}

	private String getKey(String key){
		return name + "_" + key;
	}
}

 

 

b.缓存类  MemcachedCache.java  

 

import net.rubyeye.xmemcached.MemcachedClient;

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

public class MemcachedCache implements Cache{
	private final String name;
	private final MemcachedClient memcachedClient;
	private final MemCache memCache;
	
	public MemcachedCache(String name, int expire, MemcachedClient memcachedClient){
		this.name = name;
		this.memcachedClient = memcachedClient; 
		this.memCache = new MemCache(name, expire, memcachedClient);
	}

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

	@Override
	public void evict(Object key){
		memCache.delete(key.toString());
	}

	@Override
	public ValueWrapper get(Object key){
		ValueWrapper wrapper = null;
		Object value = memCache.get(key.toString());
		if (value != null){
			wrapper = new SimpleValueWrapper(value);
		}
		return wrapper;
	}

	@Override
	public String getName(){
		return this.name;
	}

	@Override
	public MemcachedClient getNativeCache(){
		return this.memcachedClient;
	}

	@Override
	public void put(Object key, Object value){
		memCache.put(key.toString(), value);
	}
}

 

 

c.缓存管理类  MemcachedCacheManager.java

 

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import net.rubyeye.xmemcached.MemcachedClient;

import org.springframework.cache.Cache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;

public class MemcachedCacheManager extends AbstractTransactionSupportingCacheManager {
	private ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
	private Map<String, Integer> expireMap = new HashMap<String, Integer>();

	private MemcachedClient memcachedClient;

	public MemcachedCacheManager(){
	}

	@Override
	protected Collection<? extends Cache> loadCaches(){
		Collection<Cache> values = cacheMap.values();
		return values;
	}

	@Override
	public Cache getCache(String name){
		Cache cache = cacheMap.get(name);
		if (cache == null){
			Integer expire = expireMap.get(name);
			if (expire == null){
				expire = 0;
				expireMap.put(name, expire);
			}
			cache = new MemcachedCache(name, expire.intValue(), memcachedClient);
			cacheMap.put(name, cache);
		}
		return cache;
	}

	public void setMemcachedClient(MemcachedClient memcachedClient){
		this.memcachedClient = memcachedClient;
	}

	public void setConfigMap(Map<String, Integer> configMap){
		this.expireMap = configMap;
	}
}

 

 

6.数据操作类

 

@Cacheable(value="defaultCache")
public List<FmSupplier> getEnableSuppliers(){
	FmSupplierQuery query = new FmSupplierQuery();
	query.setIsDeleted(YesNoType.NO.getCode());
	query.setSupplierStatus(SupplierStatus.ENABLE.getCode());
	return fmSupplierMapper.selectListByQuery(query);
}

@Cacheable(value="defaultCache", key="#id")
public FmSupplier selectByPrimaryKey(Long id){
	return fmSupplierMapper.selectByPrimaryKey(id);
}

 

 

1.在缓存区defaultCache中获取数据,第一次请求时无数据,则会从数据库中获取并放至缓存中;

2.第二次请求时则直接从缓存中获取;

分享到:
评论

相关推荐

    面试官:Spring 注解 @After,@Around,@Before 的执行顺序是?.zip

    面试官:Spring 注解 @After,@Around,@Before 的执行顺序是?.zip 面试官:Spring 注解 @After,@Around,@Before 的执行顺序是?.zip 面试官:Spring 注解 @After,@Around,@Before 的执行顺序是?.zip 面试官:...

    spring Configurable注解用法

    在Spring框架中,`@Configurable`注解是Spring AOP(面向切面编程)的一部分,主要用于实现依赖注入(DI)到非Spring管理的对象中,比如由其他框架创建或者通过new关键字实例化的对象。这个特性使得即使在这些“不...

    Spring注解@Component、@Repository、@Service、@Controller区别.doc

    Spring 注解@Component、@Repository、@Service、@Controller 区别 在 Spring 框架中,@Component、@Repository、@Service、@Controller 是四个常用的注解,它们都是继承自 @Component 注解,用于标注不同的组件或 ...

    springboot1.x基于spring注解实现J2Cache两级缓存集成

    在本文中,我们将深入探讨如何在Spring Boot 1.x版本中使用Spring注解来实现J2Cache的两级缓存机制,其中包括一级缓存Ehcache和二级缓存Redis。通过这种方式,我们可以显著提高应用程序的性能,减少对数据库的依赖,...

    使用Spring的注解方式实现AOP的细节

    在Spring中,我们可以使用注解来声明切面、切点和通知。下面将详细介绍这些关键组件: 1. **@Aspect**: 这个注解用于标记一个类作为切面,这个类通常会包含切点和通知。 ```java @Aspect public class ...

    基于TestNG+Mockito及自动装配注解的Spring MVC集成测试

    然后,使用`@RunWith(SpringRunner.class)`和`@SpringBootTest`注解来启动一个嵌入式的Spring应用上下文,以便进行集成测试。 在实际测试编写中,我们可能会使用`@Test`注解标记的TestNG测试方法,并在其中利用`@...

    详解Spring注解--@Autowired、@Resource和@Service

    Spring注解详解 -- @Autowired、@Resource和@Service Spring框架中有三个非常重要的注解,即@Autowired、@Resource和@Service。这三个注解都是Spring框架中最常用的注解,它们都是用于解决Spring框架中的依赖注入...

    Spring注解驱动开发@尚硅谷LFY.xmind

    Spring注解驱动开发@尚硅谷LFY.xmind

    Spring demo 自动检测注解

    当我们在类的属性或方法上使用这个注解时,Spring会自动寻找匹配类型的bean并将其注入。这种方式比传统的XML配置更为便捷,因为它减少了手动编写配置文件的负担。 自动检测注解的工作机制基于以下几点: 1. **类型...

    spring boot 整合mybatis,基于@Select注解方式

    本教程将详细介绍如何在Spring Boot项目中整合MyBatis,并使用@Select注解来实现数据库查询。 首先,我们需要在Spring Boot项目中引入MyBatis的依赖。在`pom.xml`文件中添加如下依赖: ```xml &lt;groupId&gt;org....

    Spring @compenent注解详解

    在Spring框架中,`@Component`注解是核心的组件注解之一,它标志着一个类作为Spring IoC容器中的Bean。这个注解及其派生注解(如`@Service`、`@Repository`和`@Controller`)是Spring依赖注入(Dependency Injection...

    spring3注解详细

    在使用 @Autowired 时,需要在配置文件中添加 `&lt;bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /&gt;` 来启用注解处理。 ### 1.1 多个同类型 Bean 的处理 当有多...

    redis-cluster和spring集成,基于cache注解

    综上所述,"redis-cluster和spring集成,基于cache注解" 的项目是一个使用 Spring Cache 集成 Redis 集群的实例,旨在通过注解的方式简化缓存管理,提高应用性能。开发者可以通过导入提供的项目,快速了解和实践这一...

    对Spring中注解怎么实现的一些基本原理

    在Spring框架中,注解是实现依赖注入和配置的核心机制之一。本文将深入探讨Spring注解的基本原理,包括它们如何被解析、处理以及如何影响应用程序的生命周期。 首先,我们需要了解注解在Java语言中的本质。注解是一...

    hibernate-4.3.5 与Spring(Spring MVC4.0.4)注解方式集成

    以上就是Hibernate 4.3.5与Spring(Spring MVC 4.0.4)注解方式集成的主要知识点。这个压缩包中的样例源码应包含这些组件的配置文件、实体类、DAO、Service、Controller以及相关的测试类,供开发者参考学习。通过...

    spring使用注解依赖jar

    在本主题中,我们将深入探讨"spring使用注解依赖jar"这一关键知识点,包括Spring框架如何通过注解来实现依赖注入,以及如何管理相关的jar包。 首先,Spring框架的核心特性之一就是依赖注入(Dependency Injection,...

    spring使用注解暴露remoting服务

    本文将深入探讨如何使用注解来实现Spring中的Remoting服务。 首先,让我们理解什么是Remoting。Remoting是分布式系统中的一个概念,它允许不同进程或机器上的组件之间进行通信。在Spring中,我们可以使用多种技术来...

    浅谈spring 常用注解

    浅谈Spring常用注解 浅谈Spring常用注解是Spring框架中的一些基本概念,了解...掌握Spring中常用的注解对于 MASTERING SPRING Framework非常重要,本文对这些注解的分类和介绍将帮助读者更好地理解和使用这些注解。

    Spring java注解,元注解和自定义注解

    Spring框架通过集成Java注解技术极大地简化了配置文件的编写,提高了开发效率。了解并熟练掌握这些注解对于使用Spring进行高效开发至关重要。此外,学会如何使用元注解和自定义注解,可以让开发者在项目中更好地组织...

Global site tag (gtag.js) - Google Analytics