本文章牵涉到的技术点比较多:Spring Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地,所以确保您本地的Redis可用,这里还使用了MySql数据库,当然你也可以内存数据库进行测试)。这篇文章会提供对应的Eclipse代码示例,具体大体的分如下几个步骤:

(1)新建Java MavenProject;

(2)在pom.xml中添加相应的依赖包;

(3)编写Spring Boot启动类;

(4)配置application.properties;

(5)编写RedisCacheConfig配置类;

(6)编写DemoInfo测试实体类;

(7)编写DemoInfoRepository持久化类;

(8)编写DemoInfoService类;

(9)编写DemoInfoController类;

(10)测试代码是否正常运行了

(11)自定义缓存key;

 

       接下来我们看看具体每个步骤具体的操作吧。
(1)新建Java Maven Project;

       这个步骤就不细说,新建一个spring-boot-redis Java mavenproject;

 

(2)在pom.xml中添加相应的依赖包;

在Maven中添加相应的依赖包,主要有:springboot 父节点依赖;spring boot web支持;缓存服务spring-context-support;添加redis支持;JPA操作数据库;mysql 数据库驱动,具体pom.xml文件如下:

<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>com.kfit</groupId>
<artifactId>spring-boot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
 
<name>spring-boot-redis</name>
<url>http://maven.apache.org</url>
 
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--配置JDK编译版本. -->
 <java.version>1.8</java.version>
</properties>
 
<!-- spring boot父节点依赖, 
             引入这个之后相关的引入就不需要添加version配置,
               spring boot会自动选择最合适的版本进行添加。
       -->
 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.3.3.RELEASE</version>
 </parent>
 
 
<dependencies>
          
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <scope>test</scope>
 </dependency>
 
 <!-- springboot web支持:mvc,aop... -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
              
 <!-- 
                    包含支持UI模版(Velocity,FreeMarker,JasperReports),
                    邮件服务,
                    脚本服务(JRuby),
                    缓存Cache(EHCache),
                    任务计划Scheduling(uartz)。
               -->
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context-support</artifactId>
 </dependency>
 
 <!-- 添加redis支持-->
 <dependency>
 <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
 </dependency>
              
 <!-- JPA操作数据库. -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 </dependency>
              
 <!-- mysql数据库驱动. -->
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 </dependency>
           
 <!-- 单元测试. -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
              
</dependencies>
</project>
上面是完整的pom.xml文件,每个里面都进行了简单的注释。
 
(3)编写Spring Boot启动类(com.kfit.App);
package com.kfit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * Spring Boot启动类;
 *
 * @authorAngel(QQ:412887952)
 * @version v.0.1
 */
 
@SpringBootApplication
public class App {
       /**
        *-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify
        * @param args
        */
       public static voidmain(String[] args) {
              SpringApplication.run(App.class,args);
       }
}

 

(4)配置application.properties;

这里主要是配置两个资源,第一就是数据库基本信息;第二就是redis配置;第三就是JPA的配置;

Src/main/resouces/application.properties:
########################################################
###datasource 配置MySQL数据源;
########################################################
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username= root
spring.datasource.password= root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
 
 
 
########################################################
###REDIS (RedisProperties) redis基本配置;
########################################################
# database name
spring.redis.database=0
# server host1
spring.redis.host=127.0.0.1  
# server password
#spring.redis.password=
#connection port
spring.redis.port=6379
# pool settings ...
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
# name of Redis server
#spring.redis.sentinel.master=
# comma-separated list of host:portpairs
#spring.redis.sentinel.nodes=

 

########################################################
### Java Persistence Api自动进行建表
########################################################
# Specify the DBMS
spring.jpa.database= MYSQL
# Show or not log for each sqlquery
spring.jpa.show-sql= true
# Hibernate ddl auto (create,create-drop, update)
spring.jpa.hibernate.ddl-auto= update
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them tothe entity manager)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

 

 

(5)编写RedisCacheConfig配置类;

       缓存主要有几个要实现的类:其一就是CacheManager缓存管理器;其二就是具体操作实现类;其三就是CacheManager工厂类(这个可以使用配置文件配置的进行注入,也可以通过编码的方式进行实现);其四就是缓存key生产策略(当然Spring自带生成策略,但是在Redis客户端进行查看的话是系列化的key,对于我们肉眼来说就是感觉是乱码了,这里我们先使用自带的缓存策略)。

com.kfit.config/RedisCacheConfig:
package com.kfit.config;
 
importorg.springframework.cache.CacheManager;
importorg.springframework.cache.annotation.CachingConfigurerSupport;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheManager;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
 
/**

 *redis 缓存配置;

 *

 *注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;

 *

 *这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。

 *

 *普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。

 *

*@author Angel
 *@version v.0.1
 */
@Configuration
@EnableCaching//启用缓存,这个注解很重要;
publicclass RedisCacheConfig extendsCachingConfigurerSupport {
       
       
 /**
        *缓存管理器.
        *@param redisTemplate
        *@return
        */
 @Bean
       public CacheManagercacheManager(RedisTemplate<?,?>redisTemplate) {
cacheManager =newRedisCacheManager(redisTemplate);
              returncacheManager;
       }
 
       
 /**
        *redis模板操作类,类似于jdbcTemplate的一个类;
        *
        *虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;
        *
        *这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们
        *
        *自己的缓存类,比如:RedisStorage类;
        *
        *@param factory :通过Spring进行注入,参数在application.properties进行配置;
        *@return
        */
 @Bean
       publicRedisTemplate<String, String> redisTemplate(RedisConnectionFactoryfactory) {
redisTemplate = new RedisTemplate<String, String>();
 redisTemplate.setConnectionFactory(factory);
              
 //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
 //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
 //或者JdkSerializationRedisSerializer序列化方式;
//           RedisSerializer<String>redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
//           redisTemplate.setKeySerializer(redisSerializer);
//           redisTemplate.setHashKeySerializer(redisSerializer);
              
              returnredisTemplate;
       }
 
}
在以上代码有很详细的注释,在这里还是在简单的提下:
RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了;这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。
 
 
(6)编写DemoInfo测试实体类;
       编写一个测试实体类:com.kfit.bean.DemoInfo:
package com.kfit.bean;
 
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
 *测试实体类,这个随便;
 *@author Angel(
 
 *@version v.0.1
 */
@Entity
publicclass DemoInfo  implements Serializable{
       privatestatic finallong serialVersionUID = 1L;
 @Id @GeneratedValue
       privatelong id;
       private Stringname;
       private Stringpwd;
       publiclong getId() {
              returnid;
       }
       publicvoid setId(longid) {
              this.id =id;
       }
       public StringgetName() {
              returnname;
       }
       publicvoid setName(String name) {
              this.name =name;
       }
       public String getPwd(){
              returnpwd;
       }
       publicvoid setPwd(String pwd) {
              this.pwd =pwd;
       }
       
 @Override
       public StringtoString() {
              return"DemoInfo [id=" + id + ",name=" + name + ", pwd=" + pwd + "]";
       }
}
 
(7)编写DemoInfoRepository持久化类;
       DemoInfoRepository使用Spirng DataJPA实现:
com.kfit.repository.DemoInfoRepository:
package com.kfit.repository;
 
import org.springframework.data.repository.CrudRepository;
 
import com.kfit.bean.DemoInfo;
 
/**
 * DemoInfo持久化类
 *@author Angel
 *@version v.0.1
 */
publicinterfaceDemoInfoRepository extends CrudRepository<DemoInfo,Long> {
 
}
 
(8)编写DemoInfoService类;
       编写DemoInfoService,这里有两个技术方面,第一就是使用Spring @Cacheable注解方式和RedisTemplate对象进行操作,具体代码如下:
com.kfit.service.DemoInfoService:
package com.kfit.service;
 
import com.kfit.bean.DemoInfo;
 
/**
 * demoInfo服务接口
 *@author Angel
 *@version v.0.1
 */
publicinterface DemoInfoService{
       
       public DemoInfofindById(longid);
       
       publicvoiddeleteFromCache(longid);
 
       void test();
}
 
 
com.kfit.service.impl.DemoInfoServiceImpl:
package com.kfit.service.impl;
 
import javax.annotation.Resource;
 
importorg.springframework.cache.annotation.CacheEvict;
importorg.springframework.cache.annotation.Cacheable;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.core.ValueOperations;
importorg.springframework.stereotype.Service;
 
import com.kfit.bean.DemoInfo;
importcom.kfit.repository.DemoInfoRepository;
import com.kfit.service.DemoInfoService;
 
/**
 *
 *DemoInfo数据处理类
 *
 *@author Angel
 *@version v.0.1
 */
@Service
publicclass DemoInfoServiceImpl implements DemoInfoService{
       
 @Resource
       privateDemoInfoRepositorydemoInfoRepository;
       
 @Resource
       privateRedisTemplate<String,String>redisTemplate;
       
 @Override
       publicvoid test(){
valueOperations =redisTemplate.opsForValue();
 valueOperations.set("mykey4",  "random1="+Math.random());
              System.out.println(valueOperations.get("mykey4"));
       }
       
 //keyGenerator="myKeyGenerator"
 @Cacheable(value="demoInfo")  //缓存,这里没有指定key.
 @Override
       public DemoInfofindById(longid) {
              System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id);
              returndemoInfoRepository.findOne(id);
       }
       
 @CacheEvict(value="demoInfo")
 @Override
       publicvoid deleteFromCache(longid) {
              System.out.println("DemoInfoServiceImpl.delete().从缓存中删除.");
       }
       
}
 
 
(9)编写DemoInfoController类;
package com.kfit.controller;
 
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.ResponseBody;
 
import com.kfit.bean.DemoInfo;
import com.kfit.service.DemoInfoService;
 
/**
 *测试类.
 *@author Angel
 *@version v.0.1
 */
@Controller
publicclass DemoInfoController {
       
 @Autowired
 demoInfoService;
        
       
 @RequestMapping("/test")
       public@ResponseBody
 loaded = demoInfoService.findById(1);
System.out.println("loaded="+loaded);
DemoInfo  cached = demoInfoService.findById(1);
           System.out.println("cached="+cached);
 loaded = demoInfoService.findById(2);
           System.out.println("loaded2="+loaded);
           return"ok";
       }
       
       
 @RequestMapping("/delete")
       public@ResponseBody String delete(longid){
 demoInfoService.deleteFromCache(id);
           return"ok";
       }
       
 @RequestMapping("/test1")
       public@ResponseBody
 demoInfoService.test();
           System.out.println("DemoInfoController.test1()");
           return"ok";
       }
       
}
 
(10)测试代码是否正常运行了
 
启动应用程序,访问地址:http://127.0.0.1:8080/test
查看控制台可以查看:
DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2
loaded2=DemoInfo [id=2, name=张三, pwd=123456]
如果你看到以上的打印信息的话,那么说明缓存成功了。
 
访问地址:http://127.0.0.1:8080/test1
random1=0.9985031320746356
DemoInfoController.test1()
 
二次访问:http://127.0.0.1:8080/test
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
loaded2=DemoInfo [id=2, name=张三, pwd=123456]
这时候所有的数据都是执行缓存的。
 
这时候执行删除动作:http://127.0.0.1:8080/delete?id=1
然后在访问:http://127.0.0.1:8080/test
DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
loaded2=DemoInfo [id=2, name=张三, pwd=123456]
 
(11)自定义缓存key;
在com.kfit.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator ,具体实现代码如下:
 
/**
        *自定义key.
        *此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
        */
 @Override
       public KeyGeneratorkeyGenerator() {
              System.out.println("RedisCacheConfig.keyGenerator()");
              returnnew KeyGenerator(){
 @Override
                     public Objectgenerate(Object  o, Method method, Object...  objects) {
 // This willgenerate a unique key of the class name, the method name 
 //and allmethod parameters appended.
sb =newStringBuilder();
 sb.append(o.getClass().getName());
 sb.append(method.getName());
                            for (Object  obj : objects) {
sb.append(obj.toString());
                            }
                            System.out.println("keyGenerator=" +sb.toString());
                            return sb.toString();
                     }
              };
       }
 
这时候在redis的客户端查看key的话还是序列化的肉眼看到就是乱码了,那么我改变key的序列方式,这个很简单,redis底层已经有具体的实现类了,我们只需要配置下:
//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
//所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
//或者JdkSerializationRedisSerializer序列化方式;
redisSerializer =newStringRedisSerializer();//Long类型不可以会出现异常信息;
 redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
综上以上分析:RedisCacheConfig类的方法调整为:
package com.kfit.config;
 
import java.lang.reflect.Method;
 
importorg.springframework.cache.CacheManager;
importorg.springframework.cache.annotation.CachingConfigurerSupport;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.cache.interceptor.KeyGenerator;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheManager;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.serializer.RedisSerializer;
importorg.springframework.data.redis.serializer.StringRedisSerializer;
 
/**
 *redis 缓存配置;
 *
 *注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;
 *
 *这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。
 *
 *普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。
 *
 *@author Angel
 *@version v.0.1
 */
@Configuration
@EnableCaching//启用缓存,这个注解很重要;
publicclass RedisCacheConfig extendsCachingConfigurerSupport {
       
 /**
        *缓存管理器.
        *@param redisTemplate
        *@return
        */
Bean
       public CacheManagercacheManager(RedisTemplate<?,?>redisTemplate) {
cacheManager =newRedisCacheManager(redisTemplate);
              returncacheManager;
       }
 
       
 /**
        * RedisTemplate缓存操作类,类似于jdbcTemplate的一个类;
        *
        *虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;
        *
        *这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们
        *
        *自己的缓存类,比如:RedisStorage类;
        *
        *@param factory :通过Spring进行注入,参数在application.properties进行配置;
        *@return
        */
Bean
       publicRedisTemplate<String, String> redisTemplate(RedisConnectionFactoryfactory) {
redisTemplate = new RedisTemplate<String, String>();
 redisTemplate.setConnectionFactory(factory);
              
 //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
 //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
 //或者JdkSerializationRedisSerializer序列化方式;
redisSerializer =newStringRedisSerializer();//Long类型不可以会出现异常信息;
 redisTemplate.setKeySerializer(redisSerializer);
 redisTemplate.setHashKeySerializer(redisSerializer);
              
              returnredisTemplate;
       }
       
 /**
        *自定义key.
        *此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
        */
 @Override
       public KeyGeneratorkeyGenerator() {
              System.out.println("RedisCacheConfig.keyGenerator()");
              returnnew KeyGenerator(){
 @Override
                     public Objectgenerate(Object  o, Method method, Object...  objects) {
 // This willgenerate a unique key of the class name, the method name 
 //and allmethod parameters appended.
sb =newStringBuilder();
 sb.append(o.getClass().getName());
 sb.append(method.getName());
                            for (Object  obj : objects) {
sb.append(obj.toString());
                            }
                            System.out.println("keyGenerator=" +sb.toString());
                            return sb.toString();
                     }
              };
       }
 
}
 
这时候在访问地址:http://127.0.0.1:8080/test
这时候看到的Key就是:com.kfit.service.impl.DemoInfoServiceImplfindById1
在控制台打印信息是:
(1)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(2)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
(3)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(4)loaded=DemoInfo[id=1, name=张三, pwd=123456]
(5)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(6)cached=DemoInfo[id=1, name=张三, pwd=123456]
(7)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(8)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(10)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2
(11)loaded2=DemoInfo[id=2, name=张三, pwd=123456]
其中@Cacheable,@CacheEvict下节进行简单的介绍,这节的东西实在是太多了,到这里就打住吧,剩下的就需要靠你们自己进行扩展了。
         
 
【本文章是否对你有用以及是否有好的建议,请留言】
       本文章牵涉到的技术点比较多:Spring Data JPA、Redis、Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对以上这些技术点有一定的了解或者也可以先看看这篇文章,针对文章中实际的技术点在进一步了解(注意,您需要自己下载Redis Server到您的本地,所以确保您本地的Redis可用,这里还使用了MySql数据库,当然你也可以内存数据库进行测试)。这篇文章会提供对应的Eclipse代码示例,具体大体的分如下几个步骤:
(1)新建Java MavenProject;
(2)在pom.xml中添加相应的依赖包;
(3)编写Spring Boot启动类;
(4)配置application.properties;
(5)编写RedisCacheConfig配置类;
(6)编写DemoInfo测试实体类;
(7)编写DemoInfoRepository持久化类;
(8)编写DemoInfoService类;
(9)编写DemoInfoController类;
(10)测试代码是否正常运行了
(11)自定义缓存key;
 
       接下来我们看看具体每个步骤具体的操作吧。
(1)新建Java Maven Project;       这个步骤就不细说,新建一个spring-boot-redis Java mavenproject;
 
(2)在pom.xml中添加相应的依赖包;
在Maven中添加相应的依赖包,主要有:springboot 父节点依赖;spring boot web支持;缓存服务spring-context-support;添加redis支持;JPA操作数据库;mysql 数据库驱动,具体pom.xml文件如下:
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
 
<groupId>com.kfit</groupId>
<artifactId>spring-boot-redis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
 
<name>spring-boot-redis</name>
<url>http://maven.apache.org</url>
 
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--配置JDK编译版本. -->
 <java.version>1.8</java.version>
</properties>
 
<!-- spring boot父节点依赖, 
             引入这个之后相关的引入就不需要添加version配置,
               spring boot会自动选择最合适的版本进行添加。
       -->
 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.3.3.RELEASE</version>
 </parent>
 
 
<dependencies>
          
 <dependency>
 <groupId>junit</groupId>
 <artifactId>junit</artifactId>
 <scope>test</scope>
 </dependency>
 
 <!-- springboot web支持:mvc,aop... -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
              
 <!-- 
                    包含支持UI模版(Velocity,FreeMarker,JasperReports),
                    邮件服务,
                    脚本服务(JRuby),
                    缓存Cache(EHCache),
                    任务计划Scheduling(uartz)。
               -->
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-context-support</artifactId>
 </dependency>
 
 <!-- 添加redis支持-->
 <dependency>
 <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
 </dependency>
              
 <!-- JPA操作数据库. -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
 </dependency>
              
 <!-- mysql数据库驱动. -->
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 </dependency>
           
 <!-- 单元测试. -->
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
 <scope>test</scope>
 </dependency>
              
</dependencies>
</project>
上面是完整的pom.xml文件,每个里面都进行了简单的注释。
 
(3)编写Spring Boot启动类(com.kfit.App);
package com.kfit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * Spring Boot启动类;
 *
 * @authorAngel
 * @version v.0.1
 */
 
@SpringBootApplication
public class App {
       /**
        *-javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify
        * @param args
        */
       public static voidmain(String[] args) {
              SpringApplication.run(App.class,args);
       }
}
 
(4)配置application.properties;
这里主要是配置两个资源,第一就是数据库基本信息;第二就是redis配置;第三就是JPA的配置;
Src/main/resouces/application.properties:
########################################################
###datasource 配置MySQL数据源;
########################################################
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username= root
spring.datasource.password= root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.max-active=20
spring.datasource.max-idle=8
spring.datasource.min-idle=8
spring.datasource.initial-size=10
 
 
 
########################################################
###REDIS (RedisProperties) redis基本配置;
########################################################
# database name
spring.redis.database=0
# server host1
spring.redis.host=127.0.0.1  
# server password
#spring.redis.password=
#connection port
spring.redis.port=6379
# pool settings ...
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
# name of Redis server
#spring.redis.sentinel.master=
# comma-separated list of host:portpairs
#spring.redis.sentinel.nodes=
 
 
########################################################
### Java Persistence Api自动进行建表
########################################################
# Specify the DBMS
spring.jpa.database= MYSQL
# Show or not log for each sqlquery
spring.jpa.show-sql= true
# Hibernate ddl auto (create,create-drop, update)
spring.jpa.hibernate.ddl-auto= update
# Naming strategy
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them tothe entity manager)
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
 
 
 
(5)编写RedisCacheConfig配置类;
       缓存主要有几个要实现的类:其一就是CacheManager缓存管理器;其二就是具体操作实现类;其三就是CacheManager工厂类(这个可以使用配置文件配置的进行注入,也可以通过编码的方式进行实现);其四就是缓存key生产策略(当然Spring自带生成策略,但是在Redis客户端进行查看的话是系列化的key,对于我们肉眼来说就是感觉是乱码了,这里我们先使用自带的缓存策略)。
com.kfit.config/RedisCacheConfig:
package com.kfit.config;
 
importorg.springframework.cache.CacheManager;
importorg.springframework.cache.annotation.CachingConfigurerSupport;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheManager;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
 
/**
 *redis 缓存配置;
 *
 *注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;
 *
 *这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。
 *
 *普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。
 *
 *@author Angel
 *@version v.0.1
 */
@Configuration
@EnableCaching//启用缓存,这个注解很重要;
publicclass RedisCacheConfig extendsCachingConfigurerSupport {
       
       
 /**
        *缓存管理器.
        *@param redisTemplate
        *@return
        */
 @Bean
       public CacheManagercacheManager(RedisTemplate<?,?>redisTemplate) {
cacheManager =newRedisCacheManager(redisTemplate);
              returncacheManager;
       }
 
       
 /**
        *redis模板操作类,类似于jdbcTemplate的一个类;
        *
        *虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;
        *
        *这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们
        *
        *自己的缓存类,比如:RedisStorage类;
        *
        *@param factory :通过Spring进行注入,参数在application.properties进行配置;
        *@return
        */
 @Bean
       publicRedisTemplate<String, String> redisTemplate(RedisConnectionFactoryfactory) {
redisTemplate = new RedisTemplate<String, String>();
 redisTemplate.setConnectionFactory(factory);
              
 //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
 //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
 //或者JdkSerializationRedisSerializer序列化方式;
//           RedisSerializer<String>redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息;
//           redisTemplate.setKeySerializer(redisSerializer);
//           redisTemplate.setHashKeySerializer(redisSerializer);
              
              returnredisTemplate;
       }
 
}
在以上代码有很详细的注释,在这里还是在简单的提下:
RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了;这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。
 
 
(6)编写DemoInfo测试实体类;
       编写一个测试实体类:com.kfit.bean.DemoInfo:
package com.kfit.bean;
 
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
/**
 *测试实体类,这个随便;
 *@author Angel
 *@version v.0.1
 */
@Entity
publicclass DemoInfo  implements Serializable{
       privatestatic finallong serialVersionUID = 1L;
 @Id @GeneratedValue
       privatelong id;
       private Stringname;
       private Stringpwd;
       publiclong getId() {
              returnid;
       }
       publicvoid setId(longid) {
              this.id =id;
       }
       public StringgetName() {
              returnname;
       }
       publicvoid setName(String name) {
              this.name =name;
       }
       public String getPwd(){
              returnpwd;
       }
       publicvoid setPwd(String pwd) {
              this.pwd =pwd;
       }
       
 @Override
       public StringtoString() {
              return"DemoInfo [id=" + id + ",name=" + name + ", pwd=" + pwd + "]";
       }
}
 
(7)编写DemoInfoRepository持久化类;
       DemoInfoRepository使用Spirng DataJPA实现:
com.kfit.repository.DemoInfoRepository:
package com.kfit.repository;
 
import org.springframework.data.repository.CrudRepository;
 
import com.kfit.bean.DemoInfo;
 
/**
 * DemoInfo持久化类
 *@author Angel
 *@version v.0.1
 */
publicinterfaceDemoInfoRepository extends CrudRepository<DemoInfo,Long> {
 
}
 
(8)编写DemoInfoService类;
       编写DemoInfoService,这里有两个技术方面,第一就是使用Spring @Cacheable注解方式和RedisTemplate对象进行操作,具体代码如下:
com.kfit.service.DemoInfoService:
package com.kfit.service;
 
import com.kfit.bean.DemoInfo;
 
/**
 * demoInfo服务接口
 *@author Angel
 *@version v.0.1
 */
publicinterface DemoInfoService{
       
       public DemoInfofindById(longid);
       
       publicvoiddeleteFromCache(longid);
 
       void test();
}
 
 
com.kfit.service.impl.DemoInfoServiceImpl:
package com.kfit.service.impl;
 
import javax.annotation.Resource;
 
importorg.springframework.cache.annotation.CacheEvict;
importorg.springframework.cache.annotation.Cacheable;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.core.ValueOperations;
importorg.springframework.stereotype.Service;
 
import com.kfit.bean.DemoInfo;
importcom.kfit.repository.DemoInfoRepository;
import com.kfit.service.DemoInfoService;
 
/**
 *
 *DemoInfo数据处理类
 *
 *@author Angel
 *@version v.0.1
 */
@Service
publicclass DemoInfoServiceImpl implements DemoInfoService{
       
 @Resource
       privateDemoInfoRepositorydemoInfoRepository;
       
 @Resource
       privateRedisTemplate<String,String>redisTemplate;
       
 @Override
       publicvoid test(){
valueOperations =redisTemplate.opsForValue();
 valueOperations.set("mykey4",  "random1="+Math.random());
              System.out.println(valueOperations.get("mykey4"));
       }
       
 //keyGenerator="myKeyGenerator"
 @Cacheable(value="demoInfo")  //缓存,这里没有指定key.
 @Override
       public DemoInfofindById(longid) {
              System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id);
              returndemoInfoRepository.findOne(id);
       }
       
 @CacheEvict(value="demoInfo")
 @Override
       publicvoid deleteFromCache(longid) {
              System.out.println("DemoInfoServiceImpl.delete().从缓存中删除.");
       }
       
}
 
 
(9)编写DemoInfoController类;
package com.kfit.controller;
 
importorg.springframework.beans.factory.annotation.Autowired;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.ResponseBody;
 
import com.kfit.bean.DemoInfo;
import com.kfit.service.DemoInfoService;
 
/**
 *测试类.
 *@author Angel
 *@version v.0.1
 */
@Controller
publicclass DemoInfoController {
       
 @Autowired
 demoInfoService;
        
       
 @RequestMapping("/test")
       public@ResponseBody
 loaded = demoInfoService.findById(1);
System.out.println("loaded="+loaded);
DemoInfo  cached = demoInfoService.findById(1);
           System.out.println("cached="+cached);
 loaded = demoInfoService.findById(2);
           System.out.println("loaded2="+loaded);
           return"ok";
       }
       
       
 @RequestMapping("/delete")
       public@ResponseBody String delete(longid){
 demoInfoService.deleteFromCache(id);
           return"ok";
       }
       
 @RequestMapping("/test1")
       public@ResponseBody
 demoInfoService.test();
           System.out.println("DemoInfoController.test1()");
           return"ok";
       }
       
}

 

(10)测试代码是否正常运行了

 

启动应用程序,访问地址:http://127.0.0.1:8080/test

查看控制台可以查看:

DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2
loaded2=DemoInfo [id=2, name=张三, pwd=123456]

如果你看到以上的打印信息的话,那么说明缓存成功了。

 

访问地址:http://127.0.0.1:8080/test1

random1=0.9985031320746356
DemoInfoController.test1()
 
二次访问:http://127.0.0.1:8080/test
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
loaded2=DemoInfo [id=2, name=张三, pwd=123456]

这时候所有的数据都是执行缓存的。

 

这时候执行删除动作:http://127.0.0.1:8080/delete?id=1

然后在访问:http://127.0.0.1:8080/test

DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
loaded=DemoInfo [id=1, name=张三, pwd=123456]
cached=DemoInfo [id=1, name=张三, pwd=123456]
loaded2=DemoInfo [id=2, name=张三, pwd=123456]

 

(11)自定义缓存key;

在com.kfit.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator ,具体实现代码如下:

/**
        *自定义key.
        *此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
        */
 @Override
       public KeyGeneratorkeyGenerator() {
              System.out.println("RedisCacheConfig.keyGenerator()");
              returnnew KeyGenerator(){
 @Override
                     public Objectgenerate(Object  o, Method method, Object...  objects) {
 // This willgenerate a unique key of the class name, the method name 
 //and allmethod parameters appended.
sb =newStringBuilder();
 sb.append(o.getClass().getName());
 sb.append(method.getName());
                            for (Object  obj : objects) {
sb.append(obj.toString());
                            }
                            System.out.println("keyGenerator=" +sb.toString());
                            return sb.toString();
                     }
              };
       }

这时候在redis的客户端查看key的话还是序列化的肉眼看到就是乱码了,那么我改变key的序列方式,这个很简单,redis底层已经有具体的实现类了,我们只需要配置下:

//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
//所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
//或者JdkSerializationRedisSerializer序列化方式;
redisSerializer =newStringRedisSerializer();//Long类型不可以会出现异常信息;
 redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
综上以上分析:RedisCacheConfig类的方法调整为:
package com.kfit.config;
 
import java.lang.reflect.Method;
 
importorg.springframework.cache.CacheManager;
importorg.springframework.cache.annotation.CachingConfigurerSupport;
importorg.springframework.cache.annotation.EnableCaching;
importorg.springframework.cache.interceptor.KeyGenerator;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.data.redis.cache.RedisCacheManager;
importorg.springframework.data.redis.connection.RedisConnectionFactory;
importorg.springframework.data.redis.core.RedisTemplate;
importorg.springframework.data.redis.serializer.RedisSerializer;
importorg.springframework.data.redis.serializer.StringRedisSerializer;

/**

 *redis 缓存配置;

 *

 *注意:RedisCacheConfig这里也可以不用继承 :CachingConfigurerSupport,也就是直接一个普通的Class就好了;

 *

 *这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。

 *

 *普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。

*
 *@author Angel
 *@version v.0.1
 */
@Configuration
@EnableCaching//启用缓存,这个注解很重要;
publicclass RedisCacheConfig extendsCachingConfigurerSupport {
       
 /**
        *缓存管理器.
        *@param redisTemplate
        *@return
        */
Bean
       public CacheManagercacheManager(RedisTemplate<?,?>redisTemplate) {
cacheManager =newRedisCacheManager(redisTemplate);
              returncacheManager;
       }
 
       
 /**
        * RedisTemplate缓存操作类,类似于jdbcTemplate的一个类;
        *
        *虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活;
        *
        *这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们
        *
        *自己的缓存类,比如:RedisStorage类;
        *
        *@param factory :通过Spring进行注入,参数在application.properties进行配置;
        *@return
        */
Bean
       publicRedisTemplate<String, String> redisTemplate(RedisConnectionFactoryfactory) {
redisTemplate = new RedisTemplate<String, String>();
 redisTemplate.setConnectionFactory(factory);
              
 //key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误;
 //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer
 //或者JdkSerializationRedisSerializer序列化方式;
redisSerializer =newStringRedisSerializer();//Long类型不可以会出现异常信息;
 redisTemplate.setKeySerializer(redisSerializer);
 redisTemplate.setHashKeySerializer(redisSerializer);
              
              returnredisTemplate;
       }
       
 /**
        *自定义key.
        *此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。
        */
 @Override
       public KeyGeneratorkeyGenerator() {
              System.out.println("RedisCacheConfig.keyGenerator()");
              returnnew KeyGenerator(){
 @Override
                     public Objectgenerate(Object  o, Method method, Object...  objects) {
 // This willgenerate a unique key of the class name, the method name 
 //and allmethod parameters appended.
sb =newStringBuilder();
 sb.append(o.getClass().getName());
 sb.append(method.getName());
                            for (Object  obj : objects) {
sb.append(obj.toString());
                            }
                            System.out.println("keyGenerator=" +sb.toString());
                            return sb.toString();
                     }
              };
       }
 
}

 

这时候在访问地址:http://127.0.0.1:8080/test

这时候看到的Key就是:com.kfit.service.impl.DemoInfoServiceImplfindById1

在控制台打印信息是:

(1)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(2)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=1
(3)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(4)loaded=DemoInfo[id=1, name=张三, pwd=123456]
(5)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById1
(6)cached=DemoInfo[id=1, name=张三, pwd=123456]
(7)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(8)keyGenerator=com.kfit.service.impl.DemoInfoServiceImplfindById2
(10)DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id=2
(11)loaded2=DemoInfo[id=2, name=张三, pwd=123456]

其中@Cacheable,@CacheEvict下节进行简单的介绍,这节的东西实在是太多了,到这里就打住吧,剩下的就需要靠你们自己进行扩展了。