zoukankan      html  css  js  c++  java
  • 自定义注解

    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);
        }

    }

  • 相关阅读:
    二开案例.开发环境.从零开发第一个插件和数据字典
    二开案例.开发环境.调试插件代码
    C#中@的用法总结
    金蝶云社区年度资料合辑
    MySQL知识框架[博文汇总-持续更新]
    Redis基础篇(五)AOF与RDB比较和选择策略
    Redis基础篇(四)持久化:内存快照(RDB)
    单调栈技巧总结
    Redis基础篇(三)持久化:AOF日志
    Redis基础篇(二)高性能IO模型
  • 原文地址:https://www.cnblogs.com/yanduanduan/p/5057309.html
Copyright © 2011-2022 走看看