All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.hetianyi.common.cache.CacheableAspectResolver Maven / Gradle / Ivy

package com.github.hetianyi.common.cache;

import com.github.hetianyi.common.Const;
import com.github.hetianyi.common.util.ArchiveUtil;
import com.github.hetianyi.common.util.ExpressionParserUtil;
import com.github.hetianyi.common.util.StringUtil;
import com.google.common.primitives.Bytes;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.types.Expiration;

import java.util.concurrent.TimeUnit;

/**
 * 缓存注解切面处理类。
 *
 * @author Jason He
 * @version 1.0.4
 * @since 1.0.4
 * @date 2020-02-01
 */
public abstract class CacheableAspectResolver implements CacheAspectResolver {

    private static Logger log = LoggerFactory.getLogger(CacheableAspectResolver.class);

    /**
     * 拦截Cachable注解的方法,并将方法返回结果按需进行缓存。
     * @param joinPoint
     * @param cacheable
     * @return
     * @throws Throwable
     */
    @Around("@annotation(cacheable)")
    @Override
    public Object resolve(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable {
        if (!cacheable.enable()) {
            return joinPoint.proceed();
        }

        if (StringUtil.isNullOrEmptyTrimed(cacheable.key())) {
            throw new IllegalArgumentException("key expression cannot be empty");
        }

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Class returnType = methodSignature.getMethod().getReturnType();

        RedisConnection redisConnection = redisConnectionFactory().getConnection();

        byte[] key = ExpressionParserUtil.parse(cacheable.key(), "args", joinPoint.getArgs(), String.class).getBytes();

        byte[] cachedResult = redisConnection.get(key);
        if (null != cachedResult) {
            if (log.isDebugEnabled()) {
                log.debug("fetch result from cache: {}", new String(key));
            }
            if (cacheable.compressMinSize() > 0
                    && cachedResult.length >= Const.GZ_PREFIX.length
                    && Bytes.indexOf(cachedResult, Const.GZ_PREFIX) == 0) {
                byte[] unGzRet = ArchiveUtil.unGz(cachedResult);
                return Const.GSON.fromJson(new String(unGzRet), returnType);
            } else {
                return Const.GSON.fromJson(new String(cachedResult), returnType);
            }
        }

        Object ret = joinPoint.proceed();
        if (null == ret) {
            if (log.isDebugEnabled()) {
                log.debug("null result will not cache: {}", new String(key));
            }
            return null;
        }

        if (log.isDebugEnabled()) {
            log.debug("cache result data: {}", new String(key));
        }

        byte[] encoded = Const.GSON.toJson(ret).getBytes();
        if (cacheable.compressMinSize() > 0 && encoded.length >= cacheable.compressMinSize()) {
            byte[] gzResult = ArchiveUtil.gz(encoded);
            if (cacheable.expire() > 0) {
                redisConnection.set(key, gzResult,
                        Expiration.from(cacheable.expire(), TimeUnit.MILLISECONDS),
                        RedisStringCommands.SetOption.upsert());
            }
        } else {
            redisConnection.set(key, encoded,
                    Expiration.from(cacheable.expire(), TimeUnit.MILLISECONDS),
                    RedisStringCommands.SetOption.upsert());
        }
        return ret;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy