Spring AOP实现缓存业务

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();
    }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 使用SpringAOP可以实现缓存功能。具体实现方式是,在需要缓存的方法上添加@Cacheable注解,指定缓存的key和缓存的名称。当方法被调用时,Spring会先检查缓存中是否存在该key对应的缓存数据,如果存在则直接返回缓存数据,否则执行方法并将返回结果缓存起来。同时,还可以使用@CachePut注解更新缓存数据,或者使用@CacheEvict注解清除缓存数据。这样可以有效地提高系统性能和响应速度。 ### 回答2: 使用SpringAOP实现缓存功能的步骤如下: 1. 首先,需要在Spring配置文件中启用AOP功能,可以通过添加`<aop:aspectj-autoproxy/>`来实现。 2. 然后,创建一个用于缓存方法调用结果的类,该类需要实现`org.springframework.cache.Cache`接口,并提供对缓存的读取、写入、删除等操作方法。 3. 还需要创建一个切面类,该类需要使用`@Aspect`注解进行标记,并在需要缓存的方法上添加`@Cacheable`注解。在切面类中,使用`@Before`和`@After`等注解来定义缓存操作的切点和通知。 4. 在Spring配置文件中,将切面类声明为一个bean,并在`<aop:config>`中指定要应用缓存的方法和切面。 5. 最后,配置`ehcache.xml`(或其他缓存配置文件),并将其指定为Spring配置文件中缓存管理器的实现类,例如`<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"/>`。 这样,当被缓存的方法被调用时,AOP将切入切面类的通知方法,首先查询缓存是否存在该方法的结果,如果存在,则直接返回缓存中的结果;如果不存在,则调用原始方法,并将结果存入缓存中。在后续的调用中,如果参数相同,则直接从缓存中获取结果,从而减少了对原始方法的调用,提高了系统的性能和响应速度。 使用SpringAOP实现缓存功能可以大大简化代码,提高项目的可维护性和可扩展性,同时还能通过缓存数据减少对数据库等资源的访问,提升系统整体的性能。 ### 回答3: 使用SpringAOP可以很方便地实现缓存功能。AOP(面向切面编程)是一种编程范式,通过在程序运行时动态地将横切逻辑(如日志记录、事务管理、异常处理等)插入到应用程序的特定位置,以提供更好的代码结构和模块化。 在使用SpringAOP实现缓存功能时,我们可以通过以下步骤来实现: 1. 定义一个缓存注解:可以使用Spring提供的@Cacheable注解来定义缓存的方法。这个注解可以应用在方法上,用于标记被缓存的方法。 2. 配置缓存切面:通过AOP切面配置,将缓存注解和具体的缓存实现关联起来。可以使用Spring的@Aspect注解来定义一个切面类,该类可以包含多个增强方法用于处理缓存操作。 3. 配置缓存策略:在切面类中,可以通过使用Spring缓存管理器(如Ehcache、Redis等)来定义缓存的具体策略。可以配置缓存的过期时间、缓存的存储位置等。 4. 在目标方法中使用缓存注解:在需要被缓存的方法上添加之前定义的缓存注解。当方法被调用时,AOP切面会先检查缓存中是否存在对应的缓存数据,如果存在则直接返回缓存数据,否则执行方法逻辑并将结果存入缓存。 5. 测试缓存功能:执行目标方法,观察是否从缓存中获取数据以及方法执行的时间。 通过这种方式,我们可以很方便地在应用中加入缓存功能,提高系统性能和响应速度。同时,由于使用了AOP的方式,可以很好地解耦和复用缓存相关的代码逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值