springboot引入aop

pom.xml
		<!--aop相关依赖-->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.11</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.6.11</version>
		</dependency>
		<dependency>
			<groupId>org.assertj</groupId>
			<artifactId>assertj-core</artifactId>
		</dependency>

application.yml
spring: 
  aop:
    proxy-target-class: true  # aop配置生效

代码
/**
 * 功能描述:自定义切面注解,用于缓存
 *          key取值范围见AOPConfig常量
 **/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Cacheable {
    String key();
    String value() default "";
    int expireTime() default 3600;
}
package acw.com.sys.config;



import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author wang
 * @version 1.0
 * @className RedisConfig
 * @date 2020/9/27
 * @description Aop的方式操作Redis
 */

@Aspect
@Component
@EnableAspectJAutoProxy
public class RedisConfig {

    @Autowired
    private RedisTemplate redisTemplate;
    public static final String GET_CACHE_GET = "get";
    public static final String GET_CACHE_query = "query";
    public static final String GET_CACHE_select = "select";
    public static final String GET_CACHE_list = "list";
    public static final String SET_CACHE_ADD = "add";
    public static final String SET_CACHE_INSERT = "insert";
    public static final String SET_CACHE_SAVE = "save";
    public static final String SET_CACHE_BATCH_INSERT = "batchInsert";
    public static final String SET_CACHE_BATCH_UPDATE = "batchUpdate";
    public static final String SET_CACHE_UPDATE = "update";
    public static final String SET_CACHE_DELETE = "delete";
    /**
     * 获取缓存验证
     */
    private static final Pattern GET_CACHE_PATTERN = Pattern.compile("^((get)|(query)|(select)|(list)).*$");

    /**
     * 更新缓存验证
     */
    private static final Pattern SET_CACHE_PATTERN = Pattern.compile("^((add)|(insert)|(save)|(batchInsert)|(batchUpdate)|(update)|(delete)).*$");


    /**
     * 功能描述:定义切点,目标函数带有自定义注解Cacheable的均为切点
     **/
    @Pointcut("@annotation(acw.com.sys.annotation.Cacheable)")
    public void pointCut(){

    }

    /**    
     *  功能描述:切面逻辑,查询时,先查询缓存,缓存不存在对应数据时,穿透到数据库,然后放入缓存
     *          更新时,删除所有主键匹配目标方法所在类名的缓存    
     **/
    @Around("pointCut()")
    public Object doCache(ProceedingJoinPoint point)throws Throwable{
        Object result = null;
            Object [] args = point.getArgs();
            String arg = "";
            if (args != null && args.length>0){
                //获取目标方法第一个参数值
                arg = String.valueOf(args[0]);
            }
            //获取目标方法所在类
            String className = point.getTarget().toString().split("@")[0];
            //获取目标方法名
            String methodName = point.getSignature().getName();
            //获取目标注解
            Cacheable  cacheable
                    = ((MethodSignature)point.getSignature()).getMethod().getAnnotation(Cacheable.class);
            String redisKey = className + "." +cacheable.value()+ methodName +":" + arg;
            //查询
            if(GET_CACHE_PATTERN.matcher(cacheable.key()).matches()){
                result = redisTemplate.opsForValue().get(redisKey);
                if (result != null){//缓存有值
                    return result;
                }
                result = point.proceed();
                if (result == null){
                    result = "不存在该数据";
                }
                //数据库查询的数据放入缓存
                redisTemplate.opsForValue().set(redisKey,result,cacheable.expireTime(), TimeUnit.SECONDS);
            }else if (SET_CACHE_PATTERN.matcher(cacheable.key()).matches()){//更新
                result = point.proceed();//先更新,再删缓存,避免更新时缓存穿透,读取脏数据
                Set<String> keys = redisTemplate.keys(className+ "." +cacheable.value()+"*");
                redisTemplate.delete(keys);
            }
        return result;
    }




}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值