Spring Aopは簡単なmemcachedプラグインを実現

6803 ワード

memcachedはあまり紹介しません.つまり、分散キャッシュシステムです.典型的なNOSQLです.
次にspring aopで簡単なプラグインを実現し、annotation方式を実現し、簡単で便利なキャッシュを取得します.
まずannotationを定義しなければなりません
<strong>package org.xiezhaodong.spring.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface GetCacheVaule {

	
	public String key();//key
	
	
	
}</strong>

memcachedには異なるクライアントがたくさんあるので、自分のインタフェースを定義します.ユーザー自身で実現させる.次はインタフェースです.簡単な方法を定義します.
package org.xiezhaodong.spring.cache.cacheutil;
/**
 * 2015-1-14
 * @author xiezhaodong
 *    ,      
 */
public interface CacheSupport {
	long CACHE_TIME=2*60*60;//       2  
	
	/**
	 *     
	 * @param key  
	 * @param value  
	 * @return     
	 */
	 boolean addCache(String key,Object value);
	 
	 /**
	  *     ,       
	  * @param key  
	  * @param value  
	  * @param time     
	  * @return     
	  */
	 boolean addCache(String key,Object value,long cacheTime);
	 
	 
	 /**
	  *     
	  * @param key  
	  * @return     
	  */
	 boolean deleteCache(String key);
	 
	 /**
	  *     
	  * @param key  
	  * @return    
	  */
	 Object getCache(String key);
	 
	 /**
	  *          
	  * @param key  
	  * @param value  
	  * @return       
	  */
	 boolean replaceCache(String key,Object value);
	
}

次はうどんです.注釈の中はすべてとても詳しいです
package org.xiezhaodong.spring.cache.aop;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.xiezhaodong.spring.annotation.GetCacheVaule;
import org.xiezhaodong.spring.cache.cacheutil.CacheSupport;

/**
 * Aop   ,      
 * 
 * @author xiezhaodong
 * 
 */
public class GetCacheAop {

	private static final Log log = LogFactory.getLog(GetCacheAop.class);

	private CacheSupport cacheSupport;

	public void setCacheSupport(CacheSupport cacheSupport) {
		this.cacheSupport = cacheSupport;
	}

	public Object ProxyInvoke(ProceedingJoinPoint pjp) {
		log.info("invoke proxyinvoke method");
		Object result = null;
		//        
		Method method = getMethod(pjp);
		Annotation[] annotations = method.getDeclaredAnnotations();

		if (annotations.length == 0) {//       ,       
			try {			
				result = pjp.proceed();
				return result;
			} catch (Throwable e) {
				log.warn("your method " + method.getName()+ " have some errors");
			}
		}
		// --------------------------
		String cacheKey = getCacheKey(pjp, method);

		result = get_or_input_cache(pjp, result, cacheKey);
		
		return result;
		
	}
	/**
	 *                    
	 * @param pjp
	 * @param result
	 * @param cacheKey
	 * @return
	 */
	private Object get_or_input_cache(ProceedingJoinPoint pjp, Object result,
			String cacheKey) {
		if (cacheKey != null) {
			result = cacheSupport.getCache(cacheKey);//     ,  result  
			if(result==null){//         ,  result          
				try {
					result=pjp.proceed();
					cacheSupport.addCache(cacheKey,result);		
					return result;
				} catch (Throwable e) {
					log.warn("invoke default");
				}		
			}
			return result;//    ,    result
		}else{//             
			try {
				result=pjp.proceed();
				
			} catch (Throwable e) {
				log.warn("invoke default");
			}
		}
		return result;
	}

	/**
	 *   cache   
	 * 
	 * @param pjp
	 * @param method
	 * @return   string
	 */
	private String getCacheKey(ProceedingJoinPoint pjp, Method method) {
		if (method.isAnnotationPresent(GetCacheVaule.class)) {
			//       
			String key = method.getAnnotation(GetCacheVaule.class).key();//         

			Object[] values = pjp.getArgs();//         
			ParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();
			String[] names = discoverer.getParameterNames(method);
			Map<String, Integer> map = new ConcurrentHashMap<String, Integer>();
			for (int i = 0; i < names.length; i++) {
				map.put(names[i], i);//            hashmap
			}
			//      key 、value 
			try {
				Integer int_value = map.get(key);// hash       ,  getcachekey      
				if (int_value == null) {
					log.warn("your cachekey is not equals" + key
							+ "please check this then change them");					
				} else {
					String cache_key_real = (String) values[int_value];//         cahe 
					return cache_key_real;
				}
			} catch (Exception e) {
				log.warn("your filed " + key + " must be String.class");
			}

		}
		return null;
	}

	/**
	 *          
	 * 
	 * @param pjp
	 * @return
	 */
	private Method getMethod(ProceedingJoinPoint pjp) {
		MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
		Method method = methodSignature.getMethod();
		return method;
	}

}

次にxmlの構成で、cglibエージェントが必ず開くことに注意します
	<bean id="aimpl" class="org.xie.service.Service_A_impl"></bean>
	<bean id="bimpl" class="org.xie.service.Service_B_impl"></bean>
	
	<bean id="memDefault" class="org.xie.framework.memcached.spring.MemcachedDefault">
		<property name="cached" ref="memClient"></property>
	</bean>
	
	<bean id="cacheAop" class="org.xie.framework.memcached.spring.GetCacheAop">
	<property name="cacheSupport" ref="memDefault"></property>
	</bean>
	<aop:aspectj-autoproxy proxy-target-class="true"/> <!-- cglib     -->
	<aop:config>
	
		<aop:aspect id="myAspect" ref="cacheAop">
			<aop:pointcut id="businessService" expression="execution(* org.xie.service.*.*(..))" />
			<aop:around pointcut-ref="businessService" method="ProxyInvoke" />
		</aop:aspect>
	
	</aop:config>
では、サービス層のすべての方法がエージェントされています.では、keyはキャッシュするキー値を表します.
@Override
	@GetCacheVaule(key="id")//     id
	public Object testaop(String id) {
		
		return "sssss";
	}

実は何も言うことがないと感じて、言うのはすべてコードの中で、皆さんはすべて指摘しましょう.でも今は酔っぱらって簡単なgetcacheしか実現していないので、これからはゆっくりといろいろなapiを改善していきますので、楽しみにしていてください!!
転載は明記してくださいhttp://blog.csdn.net/a837199685