轻量级缓存@cache,@cacheclear

本文介绍了如何利用Redis和SpringAOP来实现轻量级的缓存管理,通过@cache注解进行缓存数据,@cacheclear注解清除缓存,提升应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**

轻量级缓存@cache,@cacheclear 使用redis,springaop实现


/**
 * Created by towery on 2018/10/10.
 */
@Component
@Aspect
public class CacheAOP {
    private static final Logger logger = LoggerFactory.getLogger(CacheAOP.class);

    @Autowired
    private RedisUtil redisUtil;

  //  @Pointcut("execution(* *..dao..*Mapper.*HD*(..)) || @annotation(com.towery.project.annotation.Cache)")
//    @Pointcut("execution(* *..dao..*Mapper.*HD*(..))")
//    @Pointcut("execution(* *..service..*Service.*find*(..))")
    //@Pointcut("execution(* com.towery.project.service..*Service.find*(..))")
    @Pointcut("@annotation(com.towery.project.annotation.Cache)")
    public void pointcut(){}

    @Pointcut("@annotation(com.towery.project.annotation.CacheClear)")
    public void cacheClear(){}

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取目标方法参数
        Object[] args = joinPoint.getArgs();
        String applId = "";
        StringBuilder builder = new StringBuilder();
        if (args != null && args.length > 0) {
        	builder.append(".");
            for(Object arg : args){
               if (arg instanceof Map) {
                   Map<String,Object> map = (Map<String,Object>)arg;
                   for (Map.Entry<String, Object> entry : map.entrySet()) {
                  //     System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
                       String key = entry.getKey();
                       Object value = entry.getValue();
                       // 兼容dataTables
                       if (!StringUtils.equals(key, "draw") && !StringUtils.equals(key, "page")) {
                    	   builder.append(key).append(StringUtil.checkCountName(value.toString()) ? string2Unicode(value.toString()) : value.toString());
                       }
                       
                       if (value instanceof Map) {
                           Map<String,Object> paramMap = (Map<String,Object>)value;
                           for (Map.Entry<String, Object> paramEntry : paramMap.entrySet()) {
                             //  System.out.println("Key = " + paramEntry.getKey() + ", Value = " + paramEntry.getValue());
                               String paramkey = paramEntry.getKey();
                               String paramValue = paramEntry.getValue().toString();
                               builder.append(paramkey).append(StringUtil.checkCountName(paramValue) ? paramValue : string2Unicode(paramValue));
                           }
                       } 
                   }
               } else {
            	   if (arg != null) {
            		   builder.append(arg.toString());
            	   }
               }
            }
            applId = builder.toString();
        }

      //  logger.debug("applId----------------" + applId);

        // 请求类名称
        String targetName = joinPoint.getTarget().getClass().getName();
        // 请求方法
        String methodName = joinPoint.getSignature().getName();

        //redis中key格式:请求类名称 + 请求方法 + 目标方法参数
        String redisKey = targetName + methodName + applId;
        logger.info("调用从缓存中查询的方法(search cache),cacheKey=" + redisKey);
        //获取从redis中查询到的对象
        Object objectFromRedis;
		try {
			objectFromRedis = redisUtil.getData4Object2Redis(redisKey);
			 //如果查询到了
	        if(null != objectFromRedis){
	            logger.info("从缓存中获取数据(from cache),cacheKey=" + redisKey);
	            Map<String,Object> cacheMap = (Map<String,Object>)objectFromRedis;
	            if (cacheMap.containsKey("page")) {
	            	EntyPage cachePage = (EntyPage)cacheMap.get("page");
	            	for(Object arg : args){
	                    if (arg instanceof Map) {
	                    	 Map<String,Object> map = (Map<String,Object>)arg;
	                    	 EntyPage page = (EntyPage)map.get("page");
	                    	 page.setTotalNumber(cachePage.getTotalNumber());
	                    	 break;
	                    }
	                }
	            }
	            
	            Object dataObj = cacheMap.get("data");
	            return dataObj;
	        }
	        
	        logger.info("没有从缓存中查到数据(no data from cache)");

	        //前置 没有查到,那么查询数据库
	        Object object = null;
	        object = joinPoint.proceed(args);
	        
	        Map<String,Object> resultMap = new HashMap<String, Object>();
	        resultMap.put("data", object);
	        
	        // 添加分页数据
	        for(Object arg : args){
	            if (arg instanceof Map) {
	            	 Map<String,Object> map = (Map<String,Object>)arg;
	            	 if (map.containsKey("page")) {
	            		 EntyPage page = (EntyPage)map.get("page");
	                	 resultMap.put("page", page);
	            	 }
	            	 break;
	            }
	        }
	                
	        //后置:将数据库中查询的数据放到redis中
	        logger.info("把数据库查询的数据存储到缓存中(put data to cache)");

//	        redisUtil.setData4Object2Redis(redisKey, object);
	        redisUtil.setData4Object2Redis(redisKey, resultMap);
	        //将查询到的数据返回
	        return object;
	        
		} catch (Exception e) {
			logger.info("缓存获取失败,从数据库获取数据(cache from fail,search in database)");
			Object object = null;
			object = joinPoint.proceed(args);
			return object;
		} 
    }

    @After(value = "cacheClear() && @annotation(cacheClear)", argNames = "joinPoint, cacheClear")
    public void methodAfter(JoinPoint joinPoint, CacheClear cacheClear) throws Throwable {
    	String targetName = joinPoint.getTarget().getClass().getSimpleName();
        if (StringUtils.isNoneBlank(targetName)) {
        	targetName = StringUtils.replace(targetName, "ServiceImpl", "");
        }
        String cacheKey = cacheClear.key();
        if (StringUtils.isNotBlank(cacheKey)) {
            targetName = cacheKey;
        }
        try {
			redisUtil.deleteKeyByContain(targetName);
		} catch (Exception e) {
			logger.info("key包含" + targetName + "的缓存清除失败(cache clean fail)");
		}
    }

    private String string2Unicode(String string) {
        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            // 取出每一个字符
            char c = string.charAt(i);
            // 转换为unicode
            unicode.append("\\u" + Integer.toHexString(c));
        }
        return unicode.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值