import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/** * 方法注解 * */@Retention(RetentionPolicy.RUNTIME)// @Target(ElementType.METHOD)public @interface MethodAnnotation { /** * 缓存中key的前缀 * * @return */ public String keyedPrifix(); /** * 保留的前缀名称,不会被放进MD5中的 * * @return */ String keepPrifix() default "";}
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;/** * 模型层对象注解类 */@Retention(RetentionPolicy.RUNTIME)public @interface ModelAnnotation { /** * 属性对应的表中的字段名称 * @return */ public String filedName(); }
import java.lang.reflect.Field;import java.lang.reflect.Method;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import cn.dfinder.dps.common.cache.CacheProxy;/** * 实体模型和数据库表字段映射关系工具类 利用反射机制,根据字段名称查找模型类中字段的注解 读取注解的fieldName值找到数据库中对应的字段名称 * */public class AnnotationUtils { private static final Log logger = LogFactory.getLog(CacheProxy.class); @SuppressWarnings("rawtypes") /** * @param clazz 类 * @param fieldName 类中属性的名称 * @return 表中字段的名称 */ public static String getFiledName(Class clazz, String fieldName) { String name = null; try { Field field = clazz.getDeclaredField(fieldName); ModelAnnotation annotation = field .getAnnotation(ModelAnnotation.class); name = annotation.filedName(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } return name; } /** * 得到方法的上定义的放入缓存中的前缀字符串 * * @param clazz * @param methodName * @return */ public static String getKeyedPrefix(Method method) { String keyedPrefix = null; try { MethodAnnotation annotation = method .getAnnotation(MethodAnnotation.class); if (annotation == null) { // 记录没有注解的方法 logger.info("No Annotation Method:" + method); } else { keyedPrefix = annotation.keyedPrifix(); } } catch (SecurityException e) { e.printStackTrace(); } return keyedPrefix; } public static String getKeepPrefix(Method method) { String keepPrefix = null; try { MethodAnnotation annotation = method .getAnnotation(MethodAnnotation.class); if (annotation != null) { keepPrefix = annotation.keepPrifix(); } } catch (SecurityException e) { e.printStackTrace(); } return keepPrefix; }}
@ModelAnnotation(filedName="数据库字段名") private String 自定义属性名;
数据库字段名 = AnnotationUtils.getFiledName( 对应的类名.class, "自定义属性名");
@MethodAnnotation(keyedPrifix = "缓存对应key") public 返回值 方法名(String 参数 );
调用相应的dao接口时
在调用该接口的类的构造函数中得到该实例
@Component("indexCommodityDaoFactory")public class IndexCommodityDaoFactory { /** * 创建商品分类的数据访问对象 * @return */ public static 调用的接口dao 方法名() { 调用的接口dao 名称= (调用的接口dao) new CacheProxy() .bind(new 调用的接口dao); return 名称; }}
public class CacheProxy implements InvocationHandler { private static final Log logger = LogFactory.getLog(CacheProxy.class); /** * 默认30分钟在缓存中失效 */ private static final int DEFAULT_TTL = 30 * 60; private int expireTime = DEFAULT_TTL; /** * memcached客户端访问接口 */ private JedisClient cache; Object originalObject; public Object bind(Object originalObject) { this.originalObject = originalObject; return Proxy.newProxyInstance(originalObject.getClass() .getClassLoader(), originalObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { init(); String keyedPrifix = AnnotationUtils.getKeyedPrefix(method); String keepPrifix = AnnotationUtils.getKeepPrefix(method); Object cacheData = null; // 判断是否使用的cache boolean useCache = CacheProcessor.useCache(); if (useCache) { cacheData = fetchFromCache(args, keyedPrifix, keepPrifix); } if (cacheData == null) { cacheData = method.invoke(originalObject, args); // put it into cache if (useCache && cacheData != null) { putIntoCache(cacheData, args, keyedPrifix, keepPrifix); } } return cacheData; } private void init() { cache = JedisClientFactory.getClient(); Integer ttl = CacheProcessor.getExpiretime(); if (ttl != null && ttl > 0) { expireTime = ttl; } } private String keys(Object[] args, String prifix) { List<String> values = new ArrayList<String>(); if (args != null) { for (Object arg : args) { if (arg != null) { values.add(arg.toString() + "_"); } } } // 将当前类信息编译进key,防止同一个接口,不同实现产生相同的key值 String className = originalObject.getClass().getName(); values.add(className + "_"); String keys = CachedKeyUtil.listStrToKey(prifix, values); return keys; } /** * 从缓存中取数据 * * @param args * @param prifix * @return */ private Object fetchFromCache(Object[] args, String keyedPrifix, String keepPrifix) { String keys = keys(args, keyedPrifix); if (keepPrifix != null && keepPrifix.isEmpty() == false) { keys = keepPrifix + keys; } // 从cache中取数据 Object obj = null; if (keys != null) { long start = System.currentTimeMillis(); obj = cache.get(keys); long end = System.currentTimeMillis(); long deltTime = end - start; boolean hit = false; if (obj != null) { hit = true; } logger.info("fetch data from cache,key=" + keys + ",coast=" + deltTime + "ms,hit=" + hit + ""); } return obj; } /** * 将数据放入缓存 * * @param value * @param args * @param prifix */ private void putIntoCache(Object value, Object[] args, String keyedPrifix, String keepPrifix) { String keys = keys(args, keyedPrifix); if (keepPrifix != null && keepPrifix.isEmpty() == false) { keys = keepPrifix + keys; } cache.set(keys, value, expireTime); }}
转载于:https://www.cnblogs.com/yanduanduan/p/5057309.html