Spring AOP实现缓存业务

文章介绍了如何使用AOP进行缓存业务处理,包括切入点表达式、环绕通知的使用,以及自定义注解@CacheFind来控制缓存操作。在CacheAOP类中,通过ProceedingJoinPoint实现方法调用,并根据注解参数决定是否从数据库查询或直接返回缓存数据。此外,示例展示了商品分类和商品列表的缓存实现。

AOP实现缓存业务 

AOP作用

AOP的主要的功能,实现方法扩展,对原有的业务逻辑解耦

AOP配置

切面 = 切入点表达式 + 通知方法

切入点表达式

1.bean com.jt.user 按类匹配单独的类

2.within(com.jt.*) 按类匹配控制粒度较粗.

3.execution(返回值类型 包名.类名.方法名(参数列表))

   execution(* com.jt.service..*.*(..))

4.annotation(自定义注解)

环绕通知

五大通知类型中,只有环绕通知可以控制目标方法是否执行. JoinPoint.proceed();

AOP缓存设计

设计说明

可以采用自定义注解的形式,控制缓存操作.

问题说明:

        1.  用户的key如何标识?  1.自动获取  2.允许用户自己设定

        2.  数据是否需要设定超时时间?  指定一个时间属性

自定义注解设计 CacheFind

@Target(ElementType.METHOD)//注解对谁有效
@Retention(RetentionPolicy.RUNTIME)//运行时有效
public @interface CacheFind {
    String key() default "";//如果用户设定参数,则使用用户的,如果用户没有设定参数,就使用自动生成
    int seconds() default 0;//默认值为0
}

编辑CacheAOP

/**
 * 1.添加环绕通知,使用环绕通知必须添加返回值
 * 2.拦截自定义注解
 * 需求:动态获取自定义注解中的参数
 * 工作原理说明:
 * 定义注解的变量名称   cacheFind
 * 通知参数接收名称    cacheFind
 * 除了匹配名称之外,还需要匹配类型.
 * 注意事项:
 * 1.环绕通知使用时,必须添加ProceedingJoinPoint
 * 2.并且其中的参数joinPoint,必须位于第一位.
 * 缓存实现业务思路:
 * 1.准备key		1:动态的生成key		2:用户指定的key,key是否有值.
 * 2.查询缓存
 * 2.1没有数据,执行数据库操作→执行目标方法
 * 将目标方法的返回值转化为JSON串,保存到redis中.
 * 2.2有数据,动态获取缓存数据之后利用工具API转化为真实的对象.
 */
@Component  //将对象交给spring容器管理
@Aspect     //自定义切面
public class CacheAOP {
    @Autowired
    private Jedis jedis;

    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        //调用方法,获取key
        String key = getKey(joinPoint, cacheFind);
        String value = jedis.get(key);
        Object object = null;
        try {
            if (StringUtils.isEmpty(value)) {
                //缓存中没有数据,查询数据库
                object = joinPoint.proceed();
                String json = ObjectMapperUtil.toJson(object);
                //判断是否需要超时设定
                if (cacheFind.seconds()>0) {
                    jedis.setex(key, cacheFind.seconds(), json);
                } else {
                    //该数据永不超时
                    jedis.set(key, json);
                }
            } else {
                //需要动态的获取返回值类型
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
                Class<?> targetClass = methodSignature.getReturnType();
                object = ObjectMapperUtil.toObject(value, targetClass);
            }
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return object;
    }

    //动态获取key
    private String getKey(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        //1.检查用户是否传递key
        String key = cacheFind.key();
        if (StringUtils.isEmpty(key)) {
            //包名.类名.方法名::第一个参数
            String className = joinPoint.getSignature().getDeclaringTypeName();
            String mothedName = joinPoint.getSignature().getName();
            Object arg0 = joinPoint.getArgs()[0];
            key = className + "." + mothedName + "::" + arg0;
        }
        return key;
    }
}

商品分类、商品列表实现缓存

    @Autowired
    private ItemCatMapper itemCatMapper;
    @Autowired
    private Jedis jedis;
 
    @Override
    @CacheFind//查询的注解
    public List<EasyUITree> findListByParentId(Long parentId) {
        QueryWrapper<ItemCat>queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("parent_id",parentId);
        List<ItemCat>itemCatList=itemCatMapper.selectList(queryWrapper);
        List<EasyUITree>easyUITreeList = new ArrayList<>(itemCatList.size());
        for (ItemCat itemCat: itemCatList) {
            Long id = itemCat.getId();
            String text = itemCat.getName();
            String state = itemCat.getIsParent()?"closed":"open";
            EasyUITree easyUITree = new EasyUITree(id,text,state);
            easyUITreeList.add(easyUITree);
        }
        return easyUITreeList;
    }

    @Override
    @CacheFind
    public String findItemName(Long itemCatId) {
        ItemCat itemCat = itemCatMapper.selectById(itemCatId);
        return itemCat.getName();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值