springboot--redis

版权声明:本文为博主原创文章,未经博主允许不得转载。否则切鸡鸡~~ https://blog.csdn.net/kang5789/article/details/83000601

在springboot中用redis可以做很多事情,比如:缓存、session同步、分布式锁

源码下载

1、缓存

添加缓存:@Cacheable(value="users")

原理是将返回值序列化为json串存在redis,查询的时候反序列化为对象返回。但是项目启动的以后一定要清除缓存,防止缓存对象字段改变,而redis里的缓存未过期,反序列化报错                  

移除缓存:@CacheEvict(value = "users", allEntries = true, beforeInvocation = true)  比如数据更新需要更新缓存

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.example</groupId>
	<artifactId>springboot-redis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springboot-redis</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.16.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-data-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>
server.port=9999

#redis
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.password=passw0rd
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=50
spring.redis.pool.max-wait=-1

#session
spring.session.store-type=redis
import java.util.Random;

import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CacheController {

	@CacheEvict(value = "nums", allEntries = true, beforeInvocation = true)
	@RequestMapping("num/del")
	public String delNum() {
		return "ok";
	}

	@Cacheable(value = "nums")
	@RequestMapping("nums")
	public Integer getNum() {
		int nextInt = new Random().nextInt(5000);
		return nextInt;
	}

}
package com.example.redis.config;

import java.lang.reflect.Method;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

import com.example.redis.utils.RedisUtils;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;

@Configuration
@EnableCaching
@EnableRedisHttpSession
public class RedisConfig extends CachingConfigurerSupport {

	@Autowired
	private RedisConnectionFactory factory;

	// 默认缓存过期时间1小时
	private static long REDIS_DEFAULT_EXPIRE = 3600;

	/**
	 * 申明缓存管理器,会创建一个切面(aspect)并触发Spring缓存注解的切点(pointcut) 根据类或者方法所使用的注解以及缓存的状态,这个切面会从缓存中获取数据,将数据添加到缓存之中或者从缓存中移除某个值
	 */
	@SuppressWarnings("rawtypes")
	@Bean
	public RedisCacheManager cacheManager(RedisTemplate redisTemplate) {
		RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
		cacheManager.setDefaultExpiration(REDIS_DEFAULT_EXPIRE);
		return cacheManager;
	}

	/**
	 * key生成规则
	 */
	@Bean
	public KeyGenerator keyGenerator() {
		return new KeyGenerator() {
			@Override
			public Object generate(Object target, Method method, Object... params) {
				StringBuilder sb = new StringBuilder(RedisUtils.REDIS_PREFIX_CACHE_NAME);
				sb.append(target.getClass().getName());
				sb.append(method.getName());
				for (Object obj : params) {
					sb.append(obj.toString());
				}
				return sb.toString();
			}
		};
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public RedisTemplate redisTemplate() {
		// 创建一个模板类
		RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
		// 将刚才的redis连接工厂设置到模板类中
		template.setConnectionFactory(factory);
		// 设置key的序列化器
		template.setKeySerializer(new StringRedisSerializer());
		// 设置value的序列化器
		// 使用Jackson 2,将对象序列化为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);
		template.setValueSerializer(jackson2JsonRedisSerializer);
		template.setConnectionFactory(factory);
		return template;
	}
}
package com.example.redis.config;

import java.util.Set;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import com.example.redis.utils.RedisUtils;

/**
 * 启动监听,清除redis缓存,防止实体属性改变反序列化出错
 */
@Component
public class MyApplicationRunner implements ApplicationRunner {

	private static final Logger LOGGER = LoggerFactory.getLogger(MyApplicationRunner.class);

	@Resource
	private RedisUtils redisUtils;

	@Override
	public void run(ApplicationArguments arguments) throws Exception {
		String redisPerfixCacheName = new StringBuilder(RedisUtils.REDIS_PREFIX_CACHE_NAME).append("*").toString();
		Set<String> keys = redisUtils.getKeys(redisPerfixCacheName);
		LOGGER.info("==============启动执行移除缓存,共{}条======", keys.size());
		for (String key : keys) {
			redisUtils.delete(key);
			LOGGER.info("移除了:{}", key);
		}
		LOGGER.info("===============移除缓存完毕==============");
	}

}

2、session同步,只需要添加上面的jar依赖和一行配置即可,测试一下

package com.example.redis.controller;

import javax.servlet.http.HttpServletRequest;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

// 改变端口启动两个服务,看下session是否一致
@RestController
public class SessionController {

	@RequestMapping("session/set")
	public String setSession(HttpServletRequest request, String name) {
		request.getSession().setAttribute("name", name);
		return "ok";
	}

	@RequestMapping("session/get")
	public String getSession(HttpServletRequest request) {
		String name = (String) request.getSession().getAttribute("name");
		return name;
	}

}

猜你喜欢

转载自blog.csdn.net/kang5789/article/details/83000601
今日推荐