自定义注解

自定义注解

  1. 自定义注解
/**
 1. 该注解主要实现查询操作. 
 2. 有缓存查询缓存,没缓存查询数据库
 3. @author Administrator
 4. 
 5. 操作规范:(具体实现在CacheAspect类中)
 6.     key: 
 7.        1.用户没有赋值
 8.           如果key为"",表示用户使用自动生成的key
 9.           key生成策略为:包名.类名.方法名.拼接第一个参数
 10.        2.如果用户赋值
 11.           key:使用用户的数据
 12.  seconds:
 13.     如果时间不为0,表示用户需要设定超时时间
 */
@Target({ElementType.METHOD}) //对方法生效
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache_Find {
   String key() default "";
   int  seconds() default 0;
}
  1. 对自定义注解的逻辑定义切面
//切面 = 切入点 + 通知
@Aspect          //标识切面
@Component    //交给spring容器管理
public class CacheAspect {
   @Autowired(required = false)
   private JedisCluster jedis; //注入redis集群对象
   /**
    * 利用AOP规则:动态获取注解对象
    * 步骤:
    *     1.根据key查询redis.
    *  2.没有数据,需要让目标方法执行.查询的结果保存redis
    *  3.将json串转化为返回值对象 返回.
    * @param joinPoint
    * @param cacheFind
    * @return
    */
   @Around("@annotation(cacheFind)")
   public Object around(ProceedingJoinPoint joinPoint, Cache_Find cacheFind) {
      //cacheFind必须和@Around("@annotation(cacheFind)")中的cacheFind保持一致
      Object data = null;
      String key = getKey(joinPoint,cacheFind);
      //1.从redis中获取数据
      String result = jedis.get(key);
      //2.判断缓存中是否有数据
      try {
         if(StringUtils.isEmpty(result)) {
            //2.1缓存中没有数据
            data = joinPoint.proceed();//目标方法执行,即添加了@Cache_Find注解的方法执行,查询数据库
            //2.2将返回值结果,转化为jsonStr
            String json = ObjectMapperUtil.toJSON(data);
            //2.3判断用户是否编辑时间
            //如果有时间,必须设定超时时间.
            if(cacheFind.seconds()>0) {
               int seconds = cacheFind.seconds();
               jedis.setex(key,seconds, json);//有超时时间的方法
            }else {
               jedis.set(key,json);//没有超时时间的方法
            }
            System.out.println("AOP查询数据库!!!!!");
         }else {
            //表示缓存数据不为空,将缓存数据转化为对象
            Class returnClass = getReturnClass(joinPoint);
            data = ObjectMapperUtil.toObject(result,returnClass);
            System.out.println("AOP查询缓存!!!!");
         }
      } catch (Throwable e) {
         e.printStackTrace();
         throw new RuntimeException(e);//全局处理了RuntimeException
      }
      return data;
   }

   /**
    * 获取目标方法的返回值类型,即添加了@Cache_Find注解的方法的返回值类型
    * @param joinPoint
    * @return
    */
   private Class getReturnClass(ProceedingJoinPoint joinPoint) {
      MethodSignature signature = (MethodSignature) joinPoint.getSignature();
      return signature.getReturnType();
   }

   /**
    * 动态获取key
    * @param joinPoint
    * @param cacheFind
    * @return
    */
   private String getKey(ProceedingJoinPoint joinPoint, Cache_Find cacheFind) {
      String key = cacheFind.key(); //如果使用@Cache_Find注解时,给了key值,使用给的key值
      if(StringUtils.isEmpty(key)) { //如果使用@Cache_Find注解时,没有给key值,则自动生成一个key值
         //获取添加了@Cache_Find注解的方法所在的全类名
         String className = joinPoint.getSignature().getDeclaringTypeName();
         //获取添加了@Cache_Find注解的方法名
         String methodName = joinPoint.getSignature().getName();
         if(joinPoint.getArgs().length>0)
            //joinPoint.getArgs()[0] 是获取添加了@Cache_Find注解的方法的第一个参数
            key = className+"."+methodName+"::" + joinPoint.getArgs()[0];
         else 
            key = className+"."+methodName;
      }
      return key;
   }
}
  1. 切面中使用到的一个工具类ObjectMapperUtil
/**
 * 作用: 实现对象与JSON串之间的转化
 * @author Administrator
 *
 */
public class ObjectMapperUtil {
   
   //常量对象 可以调用对象的方法 线程安全 不安全???
   private static final ObjectMapper MAPPER = new ObjectMapper();
   
   /**
    * 将检查异常转化为运行时异常.
    * @param data
    * @return
    */
   public static String toJSON(Object data) {
      String json = null;
      try {
         json = MAPPER.writeValueAsString(data);
      } catch (JsonProcessingException e) {
         e.printStackTrace();
         throw new RuntimeException(e);
      }
      
      return json;
   }
   
   
   /**
    * 根据JSON转化为对象 
    * 参数:json数据,Class
    * 返回值:由用户决定.
    */
   @SuppressWarnings("unchecked")
   public static <T> T toObject(String json,Class<T> target) {
      T obj = null;
      try {
         obj = MAPPER.readValue(json, target);
      } catch (IOException e) {
         e.printStackTrace();
         throw new RuntimeException(e);
      }
      return obj;
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个不回家的男人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值