Spring Aop implements a simple memcached small plug-in
Memcached is a distributed cache system! Is a typical NOSQL.
Next I will use spring aop to implement a Simple plug-in to implement the annotation method, which is simple and convenient for obtaining the cache.
1. First, we need to define an annotation.
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}
Because memcached has many different clients, I will define my own interface. Let users implement it on their own. The following is an interface that defines some simple methods.
Package org. xiezhaodong. spring. cache. cacheutil;/*** 2015-1-14 * @ author xiezhaodong * cache interface. You can implement the */public interface CacheSupport {long CACHE_TIME = 2*60*60; // The default cache time is 2 hours/*** add cache ** @ param key * @ param value * @ return success */boolean addCache (String key, object value);/*** add to cache, and set the cache time * @ param key * @ param value * @ param time cache time * @ return whether the cache is successful */boolean addCache (String key, Object value, long cacheTime ); /***** Delete cache * @ param key * @ return success */boolean deleteCache (String key ); /*** get cache * @ param key * @ return value */Object getCache (String key ); /*** replace the corresponding value in the cache * @ param key * @ param value * @ return whether the replacement is successful */boolean replaceCache (String key, Object value );}
Next is the cut section. The comments are detailed.
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. localVariableTa BleParameterNameDiscoverer; import org. springframework. core. parameterNameDiscoverer; import org. xiezhaodong. spring. annotation. getCacheVaule; import org. xiezhaodong. spring. cache. cacheutil. cacheSupport;/*** Aop partition class. The actual function class ** @ 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; // obtain the running Method method = getMethod (pjp); Annotation [] annotations = Method. getDeclaredAnnotations (); if (annotations. length = 0) {// if no annotation exists, directly execute 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 ;} /*** get the cache or check the cache from the database * @ 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); // get the cache, modify the value of result if (result = null) {// if there is no such cache, get the result and cache it to the cache service. try {result = pjp. proceed (); cacheSupport. addCache (cacheKey, result); return result;} catch (Throwable e) {log. warn ("invoke default") ;}} return result; // If the cache exists, return result} else {// if this annotation is not present, run try {result = pjp. proceed ();} catch (Throwable e) {log. warn ("invoke default") ;}} return result ;} /*** obtain the cache key value ** @ param pjp * @ param method * @ return returns string */private String getCacheKey (ProceedingJoinPoint pjp, Method method) {if (method. isAnnotationPresent (GetCacheVaule. class) {// If the annotation String key = method exists. getAnnotation (GetCacheVaule. class ). key (); // obtain the key value Object to be cached [] values = pjp. getArgs (); // obtain the ordered parameter value ParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer (); String [] names = discoverer. getParameterNames (method); Map
Map = new ConcurrentHashMap
(); For (int I = 0; I <names. length; I ++) {map. put (names [I], I); // put the name and corresponding sequence number into hashmap} // get the real key and value try {Integer int_value = map. get (key); // no corresponding value in hash, indicating that getcachekey and name do not match 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]; // return cache_key_real;} catch (Exception e) {log. warn ("your filed" + key + "must be String. class ") ;}} return null;}/*** get the runtime Method object ** @ param pjp * @ return */private Method getMethod (ProceedingJoinPoint pjp) {MethodSignature methodSignature = (MethodSignature) pjp. getSignature (); Method method = methodSignature. getMethod (); return method ;}}
Then configure the xml. Note that the cglib proxy must be enabled.
Aspectj-autoproxy proxy-target-class = "true"/>
Now all the methods at the service layer are proxies. In this case, the key indicates the key value to be cached.
@ Override @ GetCacheVaule (key = "id") // indicates the idpublic Object testaop (String id) {return "sssss ";}
In fact, I feel that there is nothing to talk about. All I want to talk about is in the Code. Please give me some advice. However, at present, only getcache is implemented. In the future, I will gradually improve various APIs. So stay tuned !!
Reprinted please indicate http://blog.csdn.net/a837199685