博客
关于我
springboot整合spring @Cache和Redis
阅读量:796 次
发布时间:2023-03-22

本文共 7101 字,大约阅读时间需要 23 分钟。

Spring基于注解的缓存机制实践指南

Spring缓存注解概述

在Spring应用中,缓存是提升性能和减少后端负载的重要手段。Spring提供了一系列注解,简化了缓存的配置和管理。这些注解包括@Cacheable@CachePut@CacheEvict@Caching@CacheConfig等,分别用于缓存写入、更新、清除和组合操作。

@Cacheable注解

@Cacheable注解用于触发缓存写入,将方法返回值存储在缓存中,以便未来重复调用时直接从缓存中获取。最简单的使用方式是注解参数指定缓存名称:

@Cacheable("books")
public Book findBook(ISBN isbn) {
// 该方法返回的值会被存储在名为"books"的缓存中
}

一个方法可以对应多个缓存名称:

@Cacheable({"books", "isbns"})
public Book findBook(ISBN isbn) {
// 该方法的返回值会被存储在"books"和"isbns"两个缓存中
}

缓存名称可以动态配置,如使用SpEL表达式:

@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed) {
// 缓存键由ISBN号决定
}

@Cacheable还支持条件判断:

@Cacheable(cacheNames="book", condition="#name.length() < 32")
public Book findBook(String name) {
// 只有当name长度小于32时,才会存储到缓存
}

@CachePut注解

@CachePut用于更新缓存,而不影响方法的执行。它的使用方式与@Cacheable类似:

@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor) {
// 该方法的返回值会被存储到缓存中
}

强烈建议不要在同一方法中同时使用@Cacheable@CachePut,以避免潜在的副作用。

@CacheEvict注解

@CacheEvict用于清除缓存,支持批量删除:

@CacheEvict(cacheNames="books")
public void loadBooks(InputStream batch) {
// 清除名为"books"的缓存
}
@CacheEvict(cacheNames="books", allEntries=true)
public void loadBooks(InputStream batch) {
// 清除所有名为"books"的缓存条目
}

@Caching注解

@Caching允许在一个方法中同时进行多个缓存操作:

@Caching(evict = {@CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0")})
public Book importBooks(String deposit, Date date) {
// 同时清除"primary"和"secondary"缓存,并根据参数p0清除"secondary"中的条目
}

@CacheConfig注解

@CacheConfig用于在类级别配置共享的缓存设置:

@CacheConfig("books")
public class BookRepositoryImpl implements BookRepository {
@Cacheable
public Book findBook(ISBN isbn) {
// 使用"books"缓存
}
}

Redis缓存集成

在Spring Boot中集成Redis缓存:

  • pom.xml中引入Redis依赖:
  • org.springframework.boot
    spring-boot-starter-data-redis
    1. 配置Redis地址和其他参数:
    2. spring:
      redis:
      database: 0
      url: redis://user:@127.0.0.1:6379
      host: 127.0.0.1
      password:
      port: 6379
      ssl: false
      timeout: 5000
      1. 定制Redis缓存配置:
      2. @Configuration
        public class CacheConfig extends CachingConfigurerSupport {
        @Resource
        private RedisConnectionFactory factory;
        @Bean
        public KeyGenerator keyGenerator() {
        return (o, method, objects) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(o.getClass().getName()).append(".");
        sb.append(method.getName()).append(".");
        for (Object obj : objects) {
        sb.append(obj.toString());
        }
        return sb.toString();
        };
        }
        @Bean
        public RedisTemplate
        redisTemplate() {
        RedisTemplate
        template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        return template;
        }
        @Bean
        @Override
        public CacheResolver cacheResolver() {
        return new SimpleCacheResolver(cacheManager());
        }
        @Bean
        @Override
        public CacheErrorHandler errorHandler() {
        return new SimpleCacheErrorHandler();
        }
        @Bean
        @Override
        public CacheManager cacheManager() {
        RedisCacheConfiguration cacheConfiguration = defaultCacheConfig()
        .disableCachingNullValues()
        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        return RedisCacheManager.builder(factory)
        .cacheDefaults(cacheConfiguration)
        .build();
        }
        }

        测试示例

        测试@Cacheable方法

        @Test
        public void findUserTest() {
        for (int i = 0; i < 3; i++) {
        System.out.println("第" + i + "次");
        User user = userService.findUser();
        System.out.println(user);
        }
        }
        @Override
        @Cacheable(value = {"valueName", "valueName2"}, key = "'keyName1'")
        public User findUser() {
        System.out.println("执行方法...");
        return new User("id1", "张三", "深圳", "1234567", 18);
        }

        测试@CachePut方法

        @Test
        public void updateUserTest() {
        userService.updateUser();
        User user = userService.findUser();
        System.out.println(user);
        }
        @Override
        @CachePut(value = "valueName", key = "'keyName1'")
        public User updateUser() {
        System.out.println("更新用户...");
        return new User("id1", "李四", "北京", "1234567", 18);
        }

        测试@CacheEvict方法

        @Test
        public void clearUserTest() {
        userService.clearUser();
        User user = userService.findUser();
        System.out.println(user);
        }
        @Override
        @CacheEvict(value = "valueName", allEntries = true)
        public void clearUser() {
        System.out.println("清除缓存...");
        }

        代码示例

        User类

        package com.wwj.springboot.model;
        import java.io.Serializable;
        public class User implements Serializable {
        private String id;
        private String name;
        private String address;
        private String tel;
        private Integer age;
        // 以下方法省略
        }

        CacheTest类

        package com.wwj.springboot.cache;
        import com.wwj.springboot.model.User;
        import com.wwj.springboot.service.UserService;
        import org.junit.Test;
        import org.springframework.boot.test.context.SpringBootTest;
        import org.springframework.cache.annotation.EnableCaching;
        import org.springframework.test.context.junit4.SpringRunner;
        import javax.annotation.Resource;
        @SpringBootTest
        @EnableCaching
        public class CacheTest {
        @Resource
        private UserService userService;
        @Test
        public void findUserTest() {
        for (int i = 0; i < 3; i++) {
        System.out.println("第" + i + "次");
        User user = userService.findUser();
        System.out.println(user);
        }
        }
        @Test
        public void updateUserTest() {
        userService.updateUser();
        User user = userService.findUser();
        System.out.println(user);
        }
        @Test
        public void clearUserTest() {
        userService.clearUser();
        User user = userService.findUser();
        System.out.println(user);
        }
        }

        UserServiceImpl类

        package com.wwj.springboot.service.impl;
        import com.wwj.springboot.model.User;
        import com.wwj.springboot.service.UserService;
        import org.springframework.cache.annotation.CacheConfig;
        import org.springframework.cache.annotation.CacheEvict;
        import org.springframework.cache.annotation.CachePut;
        import org.springframework.cache.annotation.Cacheable;
        import org.springframework.stereotype.Service;
        @Service
        @CacheConfig(cacheNames = "CacheConfigName")
        public class UserServiceImpl implements UserService {
        @Override
        @Cacheable(value = {"valueName", "valueName2"}, key = "'keyName1'")
        public User findUser() {
        System.out.println("执行方法...");
        return new User("id1", "张三", "深圳", "1234567", 18);
        }
        @Override
        @CachePut(value = "valueName", key = "'keyName1'")
        public User updateUser() {
        System.out.println("更新用户...");
        return new User("id1", "李四", "北京", "1234567", 18);
        }
        @Override
        @CacheEvict(value = "valueName", allEntries = true)
        public void clearUser() {
        System.out.println("清除缓存...");
        }
        }

        总结

        通过以上配置和示例,您可以轻松地在Spring Boot项目中实现基于注解的缓存机制。Redis作为缓存存储,能够有效提升应用的性能和响应速度。在实际项目中,建议根据具体需求合理配置缓存策略,确保既能提高性能,又能保证数据的准确性和一致性。

    转载地址:http://fjqfk.baihongyu.com/

    你可能感兴趣的文章
    Objective-C实现最长字符串链(附完整源码)
    查看>>
    Objective-C实现最长递增子序列算法(附完整源码)
    查看>>
    Objective-C实现有限状态机(附完整源码)
    查看>>
    Objective-C实现有限状态自动机FSM(附完整源码)
    查看>>
    Objective-C实现有限集上给定关系的自反关系矩阵和对称闭包关系矩阵(附完整源码)
    查看>>
    Objective-C实现朴素贝叶斯算法(附完整源码)
    查看>>
    Objective-C实现杰卡德距离算法(附完整源码)
    查看>>
    Objective-C实现极值距离算法(附完整源码)
    查看>>
    Objective-C实现构造n以内的素数表(附完整源码)
    查看>>
    Objective-C实现某文件夹下文件重命名(附完整源码)
    查看>>
    Objective-C实现查找second Largest Element第二大元素算法(附完整源码)
    查看>>
    Objective-C实现查找整数数组中给定的最小数字算法(附完整源码)
    查看>>
    Objective-C实现查找给定节点数的树中可能的二叉搜索树的数量树算法(附完整源码)
    查看>>
    Objective-C实现查找链表的中间元素算法(附完整源码)
    查看>>
    Objective-C实现根据cpu和磁盘序列号生成注册码( 附完整源码)
    查看>>
    Objective-C实现格雷码序列算法(附完整源码)
    查看>>
    Objective-C实现桥接模式(附完整源码)
    查看>>
    Objective-C实现检查一个数字是否可以被另一个数字整除算法(附完整源码)
    查看>>
    Objective-C实现检查一年是否是闰年算法 (附完整源码)
    查看>>
    Objective-C实现检查三个点在 3D 中是否共线算法(附完整源码)
    查看>>