Spring4.X + Spring MVC + Mybatis3 零配置应用开发框架搭建详解(5) - Redis缓存配置
对于缓存管理,其实就是四个步骤
web
com.aitongyi.web
1.0-SNAPSHOT
4.0.0
cache
UTF-8
com.aitongyi.web
bean
${project.version}
redis.clients
jedis
2.7.2
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan(basePackages = {"com.aitongyi.web.cache"})
public class CacheConfig {
/** redis缓存服务器地址 */
@Value("${redis.host}")
private String host;
/** redis缓存服务器端口 */
@Value("${redis.port}")
private Integer port;
/** redis缓存服务器连接超时时间 */
@Value("${redis.timeout}")
private Integer timeout;
@Bean(name = "jedisPool")
public JedisPool jedispool() {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxWaitMillis(30000); // 最大等待时间
config.setMaxTotal(32); // 最大连接数
config.setMinIdle(6); // 允许最小的空闲连接数
config.setTestOnBorrow(false); // 申请到连接时是否效验连接是否有效,对性能有影响,建议关闭
config.setTestOnReturn(false); // 使用完连接放回连接池时是否效验连接是否有效,对性能有影响,建议关闭
config.setTestWhileIdle(true); // 申请到连接时,如果空闲时间大于TimeBetweenEvictionRunsMillis时间,效验连接是否有效,建议开启,对性能有效不大
config.setTimeBetweenEvictionRunsMillis(30000); //TestWhileIdle的判断依据
return new JedisPool(config, host, port, timeout);
}
}
/**
* 缓存服务
* Created by admin on 16/8/18.
*/
@Component
public class CacheService {
@Autowired
private JedisPool jedisPool;
/**
* 设置缓存对象
* @param key
* @param value
*/
public void set(String key,String value){
Jedis jedis = null;
try{
jedis = jedisPool.getResource();
jedis.set(key, value);
}finally{
if(jedis != null){
jedis.close();
}
}
}
/**
* 获取缓存对象
* @param key
* @return
*/
public String get(String key){
Jedis jedis = null;
try{
jedis = jedisPool.getResource();
return jedis.get(key);
}finally{
if(jedis != null){
jedis.close();
}
}
}
/**
* 删除缓存对象
* @param key
*/
public void del(String key){
Jedis jedis = null;
try{
jedis = jedisPool.getResource();
jedis.del(key);
}finally{
if(jedis != null){
jedis.close();
}
}
}
}
在【back】服务中的pom.xml中加入【cache】模块的依赖
com.aitongyi.web
dao
${project.version}
com.aitongyi.web
bean
${project.version}
com.aitongyi.web
service
${project.version}
com.aitongyi.web
task
${project.version}
com.aitongyi.web
cache
${project.version}
在【back】项目中的com.aitongyi.web.back.conf.WebApplicationInitializer类中加入缓存项目的配置类【CacheConfig.class】
import com.aitongyi.web.cache.conf.CacheConfig;
import com.aitongyi.web.dao.conf.DatabaseConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
/**
* 项目启动基类
* -- 整个项目的入口
*/
public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 获取配置信息
* @return
*/
@Override
protected Class>[] getRootConfigClasses() {
return new Class[] { BackConfig.class, DatabaseConfig.class, SecurityConfig.class, CacheConfig.class};
}
@Override
protected Class>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return null;
}
}
在操作业务代码时,需要一些工具类,比如json操作的fastjson,需要在pom.xml中加入依赖,
com.alibaba
fastjson
1.2.6
然后在用户控制器中加入处理逻辑
import com.aitongyi.web.bean.User;
import com.aitongyi.web.cache.CacheService;
import com.aitongyi.web.service.UserService;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 用户请求处理器
* Created by admin on 16/8/6.
*/
@Controller
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@Autowired
private CacheService cacheService;
@RequestMapping(value = "/home", method = RequestMethod.GET)
@PreAuthorize("isAuthenticated()")// isAuthenticated 如果用户不是匿名用户就返回true
public String showHomePage() {
try {
User user = userService.loadUserByUsername("admin");
// 测试缓存服务
// 缓存用户对象到redis,以用户ID区分
cacheService.set("LOGIN_USER_" + user.getId(), JSON.toJSONString(user));
// 从缓存中取出
String userStr = cacheService.get("LOGIN_USER_" + user.getId());
// 进行反序列化
User u = JSON.parseObject(userStr, User.class);
if(u != null){
logger.info("user:{}", u);
}
logger.info("load user ");
}catch (Exception e){
logger.error(e.getLocalizedMessage(), e);
}
return "/index/index";
}
}
import java.util.Date;
/**
* Created by admin on 16/8/8.
*/
public class User {
private Integer id;
private String username;
private String password;
private boolean enabled;
private Date createDate;
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("User{");
sb.append("id=").append(id);
sb.append(", username='").append(username).append('\'');
sb.append(", password='").append(password).append('\'');
sb.append(", enabled=").append(enabled);
sb.append(", createDate=").append(createDate);
sb.append('}');
return sb.toString();
}
}
在【back】项目的back.properties中,增加redis和mysql的连接配置
#redis
redis.host = 127.0.0.1
redis.port = 6380
redis.timeout = 2000
#========= Mysql ============
jdbc.driver = com.mysql.jdbc.Driver
db.url = jdbc:mysql://127.0.0.1/web?useUnicode=true&characterEncoding=UTF-8
db.username = web
db.password = 123456
db.maxtotal = 150
db.minidle = 40
db.maxidle = 60
这两个配置意味着你需要在本机安装一个redis服务器(默认端口6379),端口是6380,本机安装一个mysql,并创建一个名称为web的库,使用utf-8这个字符集,并且创建一个web的用户,密码是123456,另外需要在数据库中创建两张表,一个是【users】表,用来存储用户信息,另外一个是【authorities】表,用来存储权限信息
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
# Dump of table authorities
# ------------------------------------------------------------
DROP TABLE IF EXISTS `authorities`;
CREATE TABLE `authorities` (
`username` varchar(50) NOT NULL,
`authority` varchar(50) NOT NULL,
UNIQUE KEY `ix_auth_username` (`username`,`authority`),
CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `authorities` WRITE;
/*!40000 ALTER TABLE `authorities` DISABLE KEYS */;
INSERT INTO `authorities` (`username`, `authority`)
VALUES
('admin','ROLE_ADMIN');
/*!40000 ALTER TABLE `authorities` ENABLE KEYS */;
UNLOCK TABLES;
# Dump of table users
# ------------------------------------------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(50) NOT NULL,
`enabled` tinyint(1) NOT NULL,
`create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `ix_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` (`id`, `username`, `password`, `enabled`, `create_date`)
VALUES
(1,'admin','e10adc3949ba59abbe56e057f20f883e',1,'2016-08-18 14:51:06');
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
表创建完成,数据写入完成,启动服务器,运行back这个web项目,就可以看到登录页面,输入用户名admin,密码123456,登录,完成我们的操作。
然后看看日志,就可以看到存储缓存和打印缓存数据的日志了。如果你有兴趣,还可以在代码上打上断点,用debug模式启动,然后一步步的看运行状态!
到此,缓存就说完了,这里要提一下这个redis的key,很多时候我们开发,定义redis中的缓存key很随意,也不规范,结果导致最终key管理混乱,代码管理难度加大。通过我们的项目,可以看到,每个功能基本是分模块的,在缓存中,需要定义一个公共的KEY管理类,所有的key都通过这个公共类来声明,如果要看缓存中定义了那些Key,就可以从这个类中一目了然。
下面我们就用【UserController】中的一个缓存KEY来做例子说明一下:
原来的key是这样的:
// 缓存用户对象到redis,以用户ID区分
cacheService.set("LOGIN_USER_" + user.getId(), JSON.toJSONString(user));
// 从缓存中取出
String userStr = cacheService.get("LOGIN_USER_" + user.getId());
通过统一管理,我们要再【cache】模块下创建一个CacheKey:
/**
* 缓存Key统一管理类
* Created by admin on 16/8/18.
*/
public class CacheKey {
/**
*
* 登录用户缓存Key
* 格式 : str.login.user.{userId}
*
*/
public static final String LOGIN_USER_KEY = "str.login.user.";
}
// 缓存用户对象到redis,以用户ID区分
cacheService.set(CacheKey.LOGIN_USER_KEY + user.getId(), JSON.toJSONString(user));
// 从缓存中取出
String userStr = cacheService.get(CacheKey.LOGIN_USER_KEY + user.getId());
目录
(一)基本介绍
(二)基础框架搭建
(三)实现最基本的登录处理
(四)任务调度管理
(五)Redis缓存配置
(六)安全框架集成
(七) git版本源代码下载