zoukankan      html  css  js  c++  java
  • SpringBoot 2.x 集成 Redis

    SpringBoot 2.x 集成 Redis

    windows上搭建redis环境

    添加依赖

    此处redis客户端使用jedis。

    <!-- redis -->
    <dependency>
    	<groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
        <exclusions>
        	<exclusion>
            	<groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
            </exclusion>
            <exclusion>
                <groupId>io.lettuce</groupId>
                <artifactId>lettuce-core</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <!-- redis 客户端使用jedis -->
    <dependency>
    	<groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
    </dependency>
    
    • Jedis

      直接连接 redis server。在多线程环境下是非线程安全的,需要使用连接池,为每个Jedis实例增加物理连接。

    • Lettuce

      连接基于Netty,连接实例可以在多个线程间并发访问。因为连接实例是线程安全的,所以一个连接实例就可以满足多线程环境下的并发访问。

    添加配置

    2.0 版本之前的一些配置已被移除。使用jedis就配置jedis(如下配置),使用lettuce换下名称即可。

    # REDIS (RedisProperties)
    # Redis数据库索引(默认为0)
    spring.redis.database=0
    # Redis服务器地址
    spring.redis.host=127.0.0.1
    # Redis服务器连接端口
    spring.redis.port=6379
    # Redis服务器连接密码(默认为空)
    spring.redis.password=
    # 连接超时时间(毫秒)
    spring.redis.timeout=0ms
    # 连接池最大连接数(使用负值表示没有限制)
    spring.redis.jedis.pool.max-active=8
    # 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1ms
    # 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    # 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    

    添加redis配置类

    • SpringBoot1.5x之前,Redis配置类如下:

        @Configuration
        @EnableCaching
        public class RedisConfig extends CachingConfigurerSupport {
      
        	@Bean
        	public KeyGenerator keyGenerator() {
       			return new KeyGenerator() {
            	    @Override
            	    public Object generate(Object target, Method method, Object... params) {
                	    StringBuilder sb = new StringBuilder();
                	    sb.append(target.getClass().getName());
                	    sb.append(method.getName());
                	    for (Object obj : params) {
                    	    sb.append(obj.toString());
                	    }
                	    return sb.toString();
            	    }
        	    };
            }
      
        	@Bean
        	public CacheManager cacheManager(RedisTemplate redisTemplate) {
        		RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
        		return redisCacheManager;
        	}
        }
      
    • SpringBoot2.0 Redis配置类如下(普遍使用了build模式),

        @Configuration
        @EnableCaching
        public class RedisConfig extends CachingConfigurerSupport {
        	@Bean
        	public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        		RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).build();
        		return redisCacheManager;
        	}
      
        	@Bean
        	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        		RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        		redisTemplate.setConnectionFactory(redisConnectionFactory);
        		// key序列化
        		redisTemplate.setKeySerializer(new StringRedisSerializer());
        		// value序列化
        		redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer(Object.class));  
        		redisTemplate.afterPropertiesSet();
        		return redisTemplate;
        	}
        }
      

      缓存管理器

      • RedisCacheManager
      • SimpleCacheManager
      • NoOpCacheManager
      • ConcurrentMapCacheManager
      • CompositeCacheManager
      • EhCacheCacheManager

      序列化器

      • GenericToStringSerializer:使用Spring转换服务进行序列化;
      • JacksonJsonRedisSerializer:使用Jackson 1,将对象序列化为JSON;
      • Jackson2JsonRedisSerializer:使用Jackson 2,将对象序列化为JSON;
      • JdkSerializationRedisSerializer:使用Java序列化;
      • OxmSerializer:使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实现序列化,用于XML序列化;
      • StringRedisSerializer:序列化String类型的key和value。

    redis使用

    • 自动根据方法生成缓存

      访问/api/user/{id}接口,会将结果缓存。代码如下:

        @RestController
        @RequestMapping(value = "/api")
        public class StudentController {
      
        	@Autowired
        	OmsUserRepository omsUserRepository;
      
        	@GetMapping(value = "/user")
        	public List<OmsUser> getAllUser() {
        		return this.omsUserRepository.findAll();
        	}
      
        	@GetMapping(value = "/user/{id}")
        	@Cacheable(value = "user-key")
        	public OmsUser getUserById(@PathVariable("id") String id) {
        		return omsUserRepository.findById(id).get();
        	}
        }
      
      • @Cacheable

        表明spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中。

      • @CachePut

        表明spring应该将方法的返回值放到缓存中。在方法的调用前不会检查缓存,方法始终都会被调用。

      • @CacheEvict

        表明spring应该在缓存中清除一个或多个条目

      • @Caching

        这是一个分组的注解,能够同时应用多个其它的缓存注解。

      自定义key

      @Cacheable@CachePut都有一个名为key属性,可使用spel表达式获取值。

      • #root.args:传递给缓存方法的参数,形式为数组
      • #root.caches:该方法执行时所对应的缓存,形式为数组
      • #root.target:目标对象
      • #root.targetClass:目标对象的类,等同#root.target.class
      • #root.method:缓存方法
      • #root.methodName:缓存方法的名字,等同root.method.name
      • #result:方法调用的返回值,不能用在@Cacheable注解上
      • #Argument:任意的方法参数名(如#argName)或参数索引(如#a0#p0)

      条件化缓存

      @Cacheable@CachePut提供了两个属性用以实现条件化缓存:unlesscondition,这两个属性都接受一个SpEL表达式。

      • unless

        仅阻止将对象放进缓存,在这个方法被调用的时候,依然会去缓存中进行查找,如果找到了匹配的值,就会返回找到的值。

      • condition

        如果表达式计算结果为false,那么在这个方法调用的过程中,缓存是被禁用的。即在这个方法被调用的时候,不会去缓存进行查找,同时返回值也不会放进缓存中。

    • 使用 Template(模版)

      模版种类:

      • StringRedisTemplate
      • RedisTemplate

      测试代码:

        @RunWith(SpringRunner.class)
        @SpringBootTest
        public class TestRedis {
      
        	@Autowired
        	private StringRedisTemplate stringRedisTemplate;
      
        	@Autowired
        	private RedisTemplate redisTemplate;
      
        	@Test
        	public void test() throws Exception {
        		// set
        		stringRedisTemplate.opsForValue().set("key", "value");
        		// get
        		String value = stringRedisTemplate.opsForValue().get("key");
        		Assert.assertEquals("value", value);
        	}
      
        	@Test
        	public void testObj() throws Exception {
        		User user = new User("king", "boy", 18);
        		ValueOperations<String, User> operations = redisTemplate.opsForValue();
        		// set
        		operations.set("obj.user.key", user);
        		// get
        		User user2 = operations.get("obj.user.key");
        		Assert.assertEquals(user.getName(), user2.getName());
        		Assert.assertEquals(user.getSex(), user2.getSex());
        		Assert.assertEquals(user.getAge(), user2.getAge());
        	}
        }
      

      测试代码中User user2 = operations.get("obj.user.key")会报错java.util.LinkedHashMap cannot be cast to User。修改redis配置类,如下:

        @Configuration
        @EnableCaching
        public class RedisConfig extends CachingConfigurerSupport {
      
        	@Bean
        	public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        		RedisCacheManager redisCacheManager = RedisCacheManager.builder(connectionFactory).build();
        		return redisCacheManager;
        	}
      
        	@Bean
        	public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        		RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        		redisTemplate.setConnectionFactory(redisConnectionFactory);
        		// key序列化
        		redisTemplate.setKeySerializer(new StringRedisSerializer());
        		// value序列化
        		// 使用Jackson ,将对象序列化为JSON
        		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        		
        		//json 转对象类,不设置默认的会将json转成hashmap
        		ObjectMapper om = new ObjectMapper();
        		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        		jackson2JsonRedisSerializer.setObjectMapper(om);
      
        		redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        		redisTemplate.afterPropertiesSet();
        		return redisTemplate;
        	}
        }
      
    • 共享 session

      • 添加依赖

          <dependency>
          	<groupId>org.springframework.session</groupId>
          	<artifactId>spring-session-data-redis</artifactId>
          </dependency>
        
      • session配置

          @Configuration
          @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
          public class SessionConfig {
          }
        
      • 测试

          @RequestMapping("/uid")
          String uid(HttpSession session) {
          	UUID uid = (UUID) session.getAttribute("uid");
          	if (uid == null) {
         			uid = UUID.randomUUID();
          	}
          	session.setAttribute("uid", uid);
          	return session.getId();
          }
        

        第一次访问后生成session,第二次及以后访问获取到session值相同。redis存储session形式如下图:

  • 相关阅读:
    JDBC批处理
    SQL注入攻击及其解决方法
    JDBC配置文件的开发形式
    JDBCUtils工具类
    利用JDBC技术,模拟用户登录的过程。查询用户表,用户名和密码是否匹配,是否存在。
    JDBC进行数据库的--增--删--改--案例----纯代码
    JDBC遍历结果集---ResultSet
    软件测试(十三)
    软件测试(十二)
    软件测试(十一)
  • 原文地址:https://www.cnblogs.com/wscy/p/9241747.html
Copyright © 2011-2022 走看看