根据aop实现自定义缓存注解

这篇具有很好参考价值的文章主要介绍了根据aop实现自定义缓存注解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

根据aop实现自定义缓存注解

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.concurrent.TimeUnit;

/**
 * @author: yanchenyang958@hellobike.com
 * @date: 2023-07-04 11:26
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheAnnotation {

    /**
     * 是:全局缓存(每个用户看到的一样)
     * 否:对用户维度缓存
     *
     * @return 是否为全局
     */
    boolean isGlobal();

    /**
     * 缓存时间
     *
     * @return 缓存时间
     */
    long time();

    /**
     * 缓存单位
     *
     * @return 缓存单位
     */
    TimeUnit timeUnit();

    /**
     * 缓存和参数有关
     *
     * @return 参数
     */
    boolean paramsDependent() default false;
}


切面

package com.hello.smart.analyzer.common.cache;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.hello.smart.analyzer.common.util.UserHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 缓存切面
 *
 * @author: yanchenyang958@hellobike.com
 * @date: 2023-07-04 16:16
 */
@Aspect
@Component
public class CacheAspect {

    /**
     * 方法对应的缓存
     * key:方法名
     * value:对应的caffeine缓存
     */
    private final Map<String, Cache<String, Object>> cacheHashMap = new HashMap<>(16);

    @Pointcut("@annotation(com.hello.smart.analyzer.common.cache.CacheAnnotation)")
    public void pointcut() {
        System.out.println("进入切面执行");
    }

    @Around(value = "pointcut()")
    public Object AroundMethod(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        String className = method.getDeclaringClass().getName();
        String mapKey = className + methodName;
        CacheAnnotation cacheAnnotation = method.getAnnotation(CacheAnnotation.class);
        //去全局map中查找方法名对应的caffeine缓存
        Cache<String, Object> cache = cacheHashMap.get(mapKey);
        //获得方法名
        StringBuilder key = new StringBuilder(cacheAnnotation.isGlobal() ? mapKey : String.format("%s%s", mapKey, UserHolder.getUserEmail()));
        //如果缓存和参数值有关
        if (cacheAnnotation.paramsDependent()) {
            Object[] args = proceedingJoinPoint.getArgs();
            for (Object arg : args) {
                key.append(arg.toString());
            }
        }
        //如果缓存存在
        if (cache != null) {
            Object resp = cache.getIfPresent(key.toString());
            if (resp != null) {
                return resp;
            }
        }
        //如果缓存不存在
        try {
            Object returnObj = proceedingJoinPoint.proceed();
            if (cache == null) {
                cache = Caffeine.newBuilder()
                        .expireAfterWrite(cacheAnnotation.time(), cacheAnnotation.timeUnit())
                        .maximumSize(5000)
                        .build();
                cacheHashMap.put(mapKey, cache);
            }
            cache.put(key.toString(), returnObj);
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return cache.getIfPresent(key.toString());
    }
}

使用

根据aop实现自定义缓存注解,缓存,spring,java文章来源地址https://www.toymoban.com/news/detail-542036.html

到了这里,关于根据aop实现自定义缓存注解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring自定义注解+aop+@BindingParam

    2.1 声明切面注解  2.1.1切面对应枚举  2.2 声明绑定参数注解 4.1 ThreadLocalUtil  4.2  自定义异常

    2024年02月14日
    浏览(41)
  • spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表

    使用FieldMeta自定义注解,看个人业务自行觉得是否需要重新定义实体 实现类 :通过该实现类获取更新前后的数据。 该实现类的实现原理为:获取入参出入的id值,获取sqlSessionFactory,通过sqlSessionFactory获取selectByPrimaryKey()该方法,执行该方法可获取id对应数据更新操作前后的数

    2024年01月23日
    浏览(53)
  • Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志

    今天主要说说如何通过自定义注解的方式,在 Spring Boot 中来实现 AOP 切面统一打印出入参日志。小伙伴们可以收藏一波。 废话不多说,进入正题! 在看看实现方法之前,我们先看下切面日志输出效果咋样: 从上图中可以看到,每个对于每个请求,开始与结束一目了然,并且

    2024年02月08日
    浏览(49)
  • spring-自定义AOP面向切面注解--统一切面处理-登陆信息采集

    2023华为OD统一考试(A+B卷)题库清单-带答案(持续更新)or2023年华为OD真题机考题库大全-带答案(持续更新) 1. 先写一个登陆记录注解(//记录:XXX时间,XXX姓名,XX系统,登录成功) 2. 写一个切面对注解进行处理(业务逻辑处理,记录登陆的信息) 3.写一个登录的控制类,

    2024年02月13日
    浏览(38)
  • 注解实现(基于Spring AOP)

    切入点表达式 Spring AOP 支持的切入点主要有以下几种: execution:用于匹配方法执行的连接点。这是最常用的切入点指示器。你可以指定具体的方法,或者类来匹配。 例如: execution(* com.example.service.*.*(..)) ,这个表达式表示匹配 com.example.service 包下的所有类的所有方法。 wit

    2024年02月16日
    浏览(42)
  • javaee spring aop 注解实现

    2024年02月09日
    浏览(45)
  • redis + AOP + 自定义注解实现接口限流

    限流(rate limiting) ​ 是指在一定时间内,对某些资源的访问次数进行限制,以避免资源被滥用或过度消耗。限流可以防止服务器崩溃、保证用户体验、提高系统可用性。 限流的方法有很多种,常见的有以下几种: 漏桶算法: ​漏桶算法通过一个固定大小的漏桶来模拟流量

    2024年02月03日
    浏览(35)
  • Spring Boot入门(23):记录接口日志再也不难!用AOP和自定义注解给Spring Boot加上日志拦截器!

            在上两期中,我们着重介绍了如何集成使用 Logback 与 log4j2 日志框架的使用,今天我们讲解的主题依旧跟日志有关,不过不是使用何种开源框架,而是自己动手造。         Spring的核心之一AOP;AOP翻译过来叫面向切面编程, 核心就是这个切面. 切面表示从业务逻辑中

    2024年02月11日
    浏览(56)
  • springboot自定义注解+aop+redis实现延时双删

    redis作为用的非常多的缓存数据库,在多线程场景下,可能会出现数据库与redis数据不一致的现象 数据不一致的现象:https://blog.csdn.net/m0_73700925/article/details/133447466 这里采用aop+redis来解决这个方法: 删除缓存 更新数据库 延时一定时间,比如500ms 删除缓存 这里之所以要延时一

    2024年01月17日
    浏览(43)
  • springboot3使用自定义注解+AOP+redis优雅实现防重复提交

      ⛰️个人主页:     蒾酒 🔥 系列专栏 :《spring boot实战》 🌊 山高路远,行路漫漫,终有归途 目录 写在前面 实现思路 实现步骤 1.定义防重复提交注解 2.编写一个切面去发现该注解然后执行防重复提交逻辑 3.测试 依赖条件 1.接口上标记防重复提交注解 2.接口测试 写在最

    2024年04月11日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包