Spring4.X + Spring MVC + Mybatis3 零配置应用开发框架搭建详解(5) - Redis缓存配置

转自:http://blog.csdn.net/chwshuang/article/details/52238728

目录(?)[+]

Spring4.X + spring MVC + Mybatis3 零配置应用开发框架搭建详解(5) - Redis缓存配置

对于缓存管理,其实就是四个步骤

  • 第一,在【cache】组件中的pom.xml中加入redis的第三方java客户端jedis的jar包
  • 第二,通过编写一个缓存配置类,来管理连接池
  • 第三,编写缓存服务,提供缓存操作接口
  • 第四,在需要使用缓存服务的【back】服务中,加入项目依赖,其他任何服务需要使用缓存服务,都可以配置类似的依赖
  • 第五,在【back】服务启动配置中加入缓存配置类,以保障缓存服务能再服务启动的时候初始化
  • 第六,在需要使用缓存服务的模块中,编写业务代码,完成缓存操作。

1. 加入缓存jar包依赖配置

[sql]  view plain  copy
 print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"  
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  5.     <parent>  
  6.         <artifactId>web</artifactId>  
  7.         <groupId>com.aitongyi.web</groupId>  
  8.         <version>1.0-SNAPSHOT</version>  
  9.     </parent>  
  10.     <modelVersion>4.0.0</modelVersion>  
  11.   
  12.     <artifactId>cache</artifactId>  
  13.   
  14.     <properties>  
  15.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
  16.     </properties>  
  17.   
  18.     <dependencies>  
  19.         <!-- CacheService缓存服务中需要用到的对象依赖    -->  
  20.         <dependency>  
  21.             <groupId>com.aitongyi.web</groupId>  
  22.             <artifactId>bean</artifactId>  
  23.             <version>${project.version}</version>  
  24.         </dependency>  
  25.         <!-- Redis依赖    -->  
  26.         <dependency>  
  27.             <groupId>redis.clients</groupId>  
  28.             <artifactId>jedis</artifactId>  
  29.             <version>2.7.2</version>  
  30.         </dependency>  
  31.     </dependencies>  
  32. </project>  


2. 创建配置对象

  

[sql]  view plain  copy
 print ?
  1. import org.springframework.beans.factory.annotation.Value;  
  2. import org.springframework.context.annotation.Bean;  
  3. import org.springframework.context.annotation.ComponentScan;  
  4. import org.springframework.context.annotation.Configuration;  
  5. import org.springframework.context.annotation.EnableAspectJAutoProxy;  
  6.   
  7.   
  8. import redis.clients.jedis.JedisPool;  
  9. import redis.clients.jedis.JedisPoolConfig;  
  10.   
  11. @Configuration  
  12. @EnableAspectJAutoProxy  
  13. @ComponentScan(basePackages = {"com.aitongyi.web.cache"})  
  14. public class CacheConfig {  
  15.     /** redis缓存服务器地址    */  
  16.     @Value("${redis.host}")  
  17.     private String host;  
  18.     /** redis缓存服务器端口    */  
  19.     @Value("${redis.port}")  
  20.     private Integer port;  
  21.     /** redis缓存服务器连接超时时间    */  
  22.     @Value("${redis.timeout}")  
  23.     private Integer timeout;  
  24.   
  25.     @Bean(name = "jedisPool")  
  26.     public JedisPool jedispool() {  
  27.         JedisPoolConfig config = new JedisPoolConfig();  
  28.         config.setMaxWaitMillis(30000); //  最大等待时间  
  29.         config.setMaxTotal(32);         //  最大连接数  
  30.         config.setMinIdle(6);           //  允许最小的空闲连接数  
  31.         config.setTestOnBorrow(false);  //  申请到连接时是否效验连接是否有效,对性能有影响,建议关闭  
  32.         config.setTestOnReturn(false);  //  使用完连接放回连接池时是否效验连接是否有效,对性能有影响,建议关闭  
  33.         config.setTestWhileIdle(true);  //  申请到连接时,如果空闲时间大于TimeBetweenEvictionRunsMillis时间,效验连接是否有效,建议开启,对性能有效不大  
  34.         config.setTimeBetweenEvictionRunsMillis(30000); //TestWhileIdle的判断依据  
  35.         return new JedisPool(config, host, port, timeout);  
  36.     }  
  37. }  


3. 创建缓存服务

[sql]  view plain  copy
 print ?
  1. /**  
  2.  * 缓存服务  
  3.  * Created by admin on 16/8/18.  
  4.  */  
  5. @Component  
  6. public class CacheService {  
  7.     @Autowired  
  8.     private JedisPool jedisPool;  
  9.   
  10.     /**  
  11.      * 设置缓存对象  
  12.      * @param key  
  13.      * @param value  
  14.      */  
  15.     public void set(String key,String value){  
  16.         Jedis jedis = null;  
  17.         try{  
  18.             jedis = jedisPool.getResource();  
  19.             jedis.set(key, value);  
  20.         }finally{  
  21.             if(jedis != null){  
  22.                 jedis.close();  
  23.             }  
  24.         }  
  25.     }  
  26.   
  27.     /**  
  28.      * 获取缓存对象  
  29.      * @param key  
  30.      * @return  
  31.      */  
  32.     public String get(String key){  
  33.         Jedis jedis = null;  
  34.         try{  
  35.             jedis = jedisPool.getResource();  
  36.             return jedis.get(key);  
  37.         }finally{  
  38.             if(jedis != null){  
  39.                 jedis.close();  
  40.             }  
  41.         }  
  42.     }  
  43.   
  44.     /**  
  45.      * 删除缓存对象  
  46.      * @param key  
  47.      */  
  48.     public void del(String key){  
  49.         Jedis jedis = null;  
  50.         try{  
  51.             jedis = jedisPool.getResource();  
  52.             jedis.del(key);  
  53.         }finally{  
  54.             if(jedis != null){  
  55.                 jedis.close();  
  56.             }  
  57.         }  
  58.     }  
  59.   
  60. }  

4. 对缓存服务的依赖管理

在【back】服务中的pom.xml中加入【cache】模块的依赖

[sql]  view plain  copy
 print ?
  1. <dependencies>  
  2.         <dependency>  
  3.             <groupId>com.aitongyi.web</groupId>  
  4.             <artifactId>dao</artifactId>  
  5.             <version>${project.version}</version>  
  6.         </dependency>  
  7.         <dependency>  
  8.             <groupId>com.aitongyi.web</groupId>  
  9.             <artifactId>bean</artifactId>  
  10.             <version>${project.version}</version>  
  11.         </dependency>  
  12.         <dependency>  
  13.             <groupId>com.aitongyi.web</groupId>  
  14.             <artifactId>service</artifactId>  
  15.             <version>${project.version}</version>  
  16.         </dependency>  
  17.         <dependency>  
  18.             <groupId>com.aitongyi.web</groupId>  
  19.             <artifactId>task</artifactId>  
  20.             <version>${project.version}</version>  
  21.         </dependency>  
  22.         <!--  缓存模块  -->  
  23.         <dependency>  
  24.             <groupId>com.aitongyi.web</groupId>  
  25.             <artifactId>cache</artifactId>  
  26.             <version>${project.version}</version>  
  27.         </dependency>  

5. 缓存配置加入项目启动配置中

在【back】项目中的com.aitongyi.web.back.conf.WebApplicationInitializer类中加入缓存项目的配置类【CacheConfig.class】

[sql]  view plain  copy
 print ?
  1. import com.aitongyi.web.cache.conf.CacheConfig;  
  2. import com.aitongyi.web.dao.conf.DatabaseConfig;  
  3. import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;  
  4.   
  5. import javax.servlet.Filter;  
  6.   
  7. /**  
  8.  * 项目启动基类  
  9.  * -- 整个项目的入口  
  10.  */  
  11. public class WebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {  
  12.     /**  
  13.      * 获取配置信息  
  14.      * @return  
  15.      */  
  16.     @Override  
  17.     protected Class<?>[] getRootConfigClasses() {  
  18.         return new Class[] { BackConfig.class, DatabaseConfig.class, SecurityConfig.class, CacheConfig.class};  
  19.     }  
  20.     @Override  
  21.     protected Class<?>[] getServletConfigClasses() {  
  22.         return new Class[] { MvcConfig.class };  
  23.     }  
  24.   
  25.     @Override  
  26.     protected String[] getServletMappings() {  
  27.         return new String[] { "/" };  
  28.     }  
  29.   
  30.     @Override  
  31.     protected Filter[] getServletFilters() {  
  32.         return null;  
  33.     }  
  34. }  


6. 缓存业务操作代码

在操作业务代码时,需要一些工具类,比如json操作的fastjson,需要在pom.xml中加入依赖,

[sql]  view plain  copy
 print ?
  1. <dependency>  
  2.     <groupId>com.alibaba</groupId>  
  3.     <artifactId>fastjson</artifactId>  
  4.     <version>1.2.6</version>  
  5. </dependency>  

然后在用户控制器中加入处理逻辑

[sql]  view plain  copy
 print ?
  1. import com.aitongyi.web.bean.User;  
  2. import com.aitongyi.web.cache.CacheService;  
  3. import com.aitongyi.web.service.UserService;  
  4. import com.alibaba.fastjson.JSON;  
  5. import org.slf4j.Logger;  
  6. import org.slf4j.LoggerFactory;  
  7. import org.springframework.beans.factory.annotation.Autowired;  
  8. import org.springframework.security.access.prepost.PreAuthorize;  
  9. import org.springframework.stereotype.Controller;  
  10. import org.springframework.web.bind.annotation.RequestMapping;  
  11. import org.springframework.web.bind.annotation.RequestMethod;  
  12.   
  13. /**  
  14.  * 用户请求处理器  
  15.  * Created by admin on 16/8/6.  
  16.  */  
  17. @Controller  
  18. public class UserController {  
  19.     private static final Logger logger = LoggerFactory.getLogger(UserController.class);  
  20.   
  21.     @Autowired  
  22.     private UserService userService;  
  23.   
  24.     @Autowired  
  25.     private CacheService cacheService;  
  26.   
  27.     @RequestMapping(value = "/home", method = RequestMethod.GET)  
  28.     @PreAuthorize("isAuthenticated()")// isAuthenticated 如果用户不是匿名用户就返回true  
  29.     public String showHomePage() {  
  30.         try {  
  31.               
  32.             User user = userService.loadUserByUsername("admin");  
  33.   
  34. //            测试缓存服务  
  35. //            缓存用户对象到redis,以用户ID区分  
  36.             cacheService.set("LOGIN_USER_" + user.getId(), JSON.toJSONString(user));  
  37. //            从缓存中取出  
  38.             String userStr = cacheService.get("LOGIN_USER_" + user.getId());  
  39. //            进行反序列化  
  40.             User u = JSON.parseObject(userStr, User.class);  
  41.             if(u != null){  
  42.                 logger.info("user:{}", u);  
  43.             }  
  44.             logger.info("load user ");  
  45.         }catch (Exception e){  
  46.             logger.error(e.getLocalizedMessage(), e);  
  47.         }  
  48.   
  49.         return "/index/index";  
  50.     }  
  51. }  

当然,直接打印user会出现 @45sd3sdf这样的情况,需要重写User的toString方法

[sql]  view plain  copy
 print ?
  1. import java.util.Date;  
  2.   
  3. /**  
  4.  * Created by admin on 16/8/8.  
  5.  */  
  6. public class User {  
  7.     private Integer id;  
  8.     private String username;  
  9.     private String password;  
  10.     private boolean enabled;  
  11.     private Date createDate;  
  12.   
  13.     public Date getCreateDate() {  
  14.         return createDate;  
  15.     }  
  16.   
  17.     public void setCreateDate(Date createDate) {  
  18.         this.createDate = createDate;  
  19.     }  
  20.   
  21.     public boolean isEnabled() {  
  22.         return enabled;  
  23.     }  
  24.   
  25.     public void setEnabled(boolean enabled) {  
  26.         this.enabled = enabled;  
  27.     }  
  28.   
  29.     public Integer getId() {  
  30.         return id;  
  31.     }  
  32.   
  33.     public void setId(Integer id) {  
  34.         this.id = id;  
  35.     }  
  36.   
  37.     public String getPassword() {  
  38.         return password;  
  39.     }  
  40.   
  41.     public void setPassword(String password) {  
  42.         this.password = password;  
  43.     }  
  44.   
  45.     public String getUsername() {  
  46.         return username;  
  47.     }  
  48.   
  49.     public void setUsername(String username) {  
  50.         this.username = username;  
  51.     }  
  52.   
  53.     @Override  
  54.     public String toString() {  
  55.         final StringBuffer sb = new StringBuffer("User{");  
  56.         sb.append("id=").append(id);  
  57.         sb.append(", username='").append(username).append('\'');  
  58.         sb.append(", password='").append(password).append('\'');  
  59.         sb.append(", enabled=").append(enabled);  
  60.         sb.append(", createDate=").append(createDate);  
  61.         sb.append('}');  
  62.         return sb.toString();  
  63.     }  
  64. }  

7. 加入数据库配置

在【back】项目的back.properties中,增加redisMySQL的连接配置

[sql]  view plain  copy
 print ?
  1. #redis  
  2. redis.host = 127.0.0.1  
  3. redis.port = 6380  
  4. redis.timeout = 2000  
  5.   
  6. #========= Mysql ============  
  7. jdbc.driver = com.mysql.jdbc.Driver  
  8. db.url = jdbc:mysql://127.0.0.1/web?useUnicode=true&characterEncoding=UTF-8  
  9. db.username = web  
  10. db.password = 123456  
  11. db.maxtotal = 150  
  12. db.minidle = 40  
  13. db.maxidle = 60  
这两个配置意味着你需要在本机安装一个redis服务器(默认端口6379),端口是6380,本机安装一个mysql,并创建一个名称为web的库,使用utf-8这个字符集,并且创建一个web的用户,密码是123456,另外需要在数据库中创建两张表,一个是【users】表,用来存储用户信息,另外一个是【authorities】表,用来存储权限信息

[sql]  view plain  copy
 print ?
  1. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;  
  2. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;  
  3. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;  
  4. /*!40101 SET NAMES utf8 */;  
  5. /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;  
  6. /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;  
  7. /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;  
  8.   
  9.   
  10. # Dump of table authorities  
  11. ------------------------------------------------------------  
  12.   
  13. DROP TABLE IF EXISTS `authorities`;  
  14.   
  15. CREATE TABLE `authorities` (  
  16.   `username` varchar(50) NOT NULL,  
  17.   `authority` varchar(50) NOT NULL,  
  18.   UNIQUE KEY `ix_auth_username` (`username`,`authority`),  
  19.   CONSTRAINT `fk_authorities_users` FOREIGN KEY (`username`) REFERENCES `users` (`username`)  
  20. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  21.   
  22. LOCK TABLES `authorities` WRITE;  
  23. /*!40000 ALTER TABLE `authorities` DISABLE KEYS */;  
  24.   
  25. INSERT INTO `authorities` (`username`, `authority`)  
  26. VALUES  
  27.     ('admin','ROLE_ADMIN');  
  28.   
  29. /*!40000 ALTER TABLE `authorities` ENABLE KEYS */;  
  30. UNLOCK TABLES;  
  31.   
  32.   
  33. # Dump of table users  
  34. ------------------------------------------------------------  
  35.   
  36. DROP TABLE IF EXISTS `users`;  
  37.   
  38. CREATE TABLE `users` (  
  39.   `id` int(11) NOT NULL AUTO_INCREMENT,  
  40.   `username` varchar(50) NOT NULL,  
  41.   `passwordvarchar(50) NOT NULL,  
  42.   `enabled` tinyint(1) NOT NULL,  
  43.   `create_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,  
  44.   PRIMARY KEY (`id`),  
  45.   UNIQUE KEY `ix_username` (`username`)  
  46. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;  
  47.   
  48. LOCK TABLES `users` WRITE;  
  49. /*!40000 ALTER TABLE `users` DISABLE KEYS */;  
  50.   
  51. INSERT INTO `users` (`id`, `username`, `password`, `enabled`, `create_date`)  
  52. VALUES  
  53.     (1,'admin','e10adc3949ba59abbe56e057f20f883e',1,'2016-08-18 14:51:06');  
  54.   
  55. /*!40000 ALTER TABLE `users` ENABLE KEYS */;  
  56. UNLOCK TABLES;  

表创建完成,数据写入完成,启动服务器,运行back这个web项目,就可以看到登录页面,输入用户名admin,密码123456,登录,完成我们的操作。

然后看看日志,就可以看到存储缓存和打印缓存数据的日志了。如果你有兴趣,还可以在代码上打上断点,用debug模式启动,然后一步步的看运行状态!



8. 缓存KEY管理最佳实践

到此,缓存就说完了,这里要提一下这个redis的key,很多时候我们开发,定义redis中的缓存key很随意,也不规范,结果导致最终key管理混乱,代码管理难度加大。通过我们的项目,可以看到,每个功能基本是分模块的,在缓存中,需要定义一个公共的KEY管理类,所有的key都通过这个公共类来声明,如果要看缓存中定义了那些Key,就可以从这个类中一目了然。

下面我们就用【UserController】中的一个缓存KEY来做例子说明一下:

原来的key是这样的:

[sql]  view plain  copy
 print ?
  1. //            缓存用户对象到redis,以用户ID区分  
  2.             cacheService.set("LOGIN_USER_" + user.getId(), JSON.toJSONString(user));  
  3. //            从缓存中取出  
  4.             String userStr = cacheService.get("LOGIN_USER_" + user.getId());  


通过统一管理,我们要再【cache】模块下创建一个CacheKey:

[sql]  view plain  copy
 print ?
  1. /**  
  2.  * 缓存Key统一管理类  
  3.  * Created by admin on 16/8/18.  
  4.  */  
  5. public class CacheKey {  
  6.   
  7.     /**  
  8.      * <pre>  
  9.      * 登录用户缓存Key  
  10.      * 格式 :  str.login.user.{userId}  
  11.      * </pre>  
  12.      */  
  13.     public static final String LOGIN_USER_KEY = "str.login.user.";  
  14. }  

然后将原来的代码改为:

[sql]  view plain  copy
 print ?
  1. //            缓存用户对象到redis,以用户ID区分  
  2.             cacheService.set(CacheKey.LOGIN_USER_KEY + user.getId(), JSON.toJSONString(user));  
  3. //            从缓存中取出  
  4.             String userStr = cacheService.get(CacheKey.LOGIN_USER_KEY + user.getId());  

通过这样的管理,所有用户都统一的缓存Key的使用,如果要查看redis中用了那些缓存key,缓存中的key代表什么意思,就一目了然了。


目录

        (一)基本介绍    
        (二)基础框架搭建
        (三)实现最基本的登录处理        
        (四)任务调度管理   
        (五)Redis缓存配置
        (六)安全框架集成

        (七) git版本源代码下载


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值