Maison >Java >javaDidacticiel >Introduction à la méthode d'intégration de Redis avec Spring Boot dans le mécanisme de mise en cache
Cet article implique de nombreux points techniques : spring Data JPA, Redis, Spring MVC, Spirng Cache, donc en lisant cet article, vous devez avoir une certaine compréhension des points techniques ci-dessus ou vous pouvez le lire d'abord Dans cet article, nous en apprendrons plus sur les points techniques réels dans l'article (notez que vous devez télécharger le serveur Redis dans votre région, alors assurez-vous que votre Redis local est disponible. La base de données MySQL est également utilisée ici. Bien sûr, vous pouvez également utiliser un base de données en mémoire). Cet article fournira des exemples de code Eclipse correspondants, qui sont grossièrement divisés en les étapes suivantes :
(1) Créez un nouveau projet Java Maven
(2) Ajoutez le code correspondant dans pom. paquet de dépendances xml ;
(3) Écrire la classe de démarrage Spring Boot ;
(4) Configurer application.properties
(5) Écrire la classe de configuration RedisCacheConfig
(6) Écrire la classe d'entité de test DemoInfo ;
(7) Écrivez la classe de persistance DemoInfoRepository ;
(8) Écrivez la classe DemoInfoService
(9) Écrivez la classe DemoInfoController
(10) Testez si le code s'exécute normalement
( 11) Clé de cache personnalisée ;
(1) Créer un nouveau projet Java Maven ;
Je n'entrerai pas dans les détails de cette étape, mais créerai un nouveau spring-boot- redis Java maven project ; 🎜>
(2) Ajoutez le package de dépendances correspondant dans pom.xml ;
Ajoutez le package de dépendances correspondant dans Maven, comprenant principalement : la dépendance du nœud parent Spring Boot ; ; service de cache spring-context-support ; ajouter la prise en charge de Redis ; base de données d'opération JPA ; pilote de base de données mysql, le fichier pom.xml spécifique est le suivant :
Ce qui précède est le fichier pom.xml complet, chacun a une annotation simple.<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.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> <!-- spring boot 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>
(3) Écrivez la classe de démarrage Spring Boot (com.kfit.App)
package com.kfit; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Spring Boot启动类; * * @author Angel(QQ:*********) * @version v.0.1 */ @SpringBootApplication public class App { /** * -javaagent:.\lib\springloaded-1.2.4.RELEASE.jar -noverify * @param args */ public static void main(String[] args) { SpringApplication.run(App.class, args); } }(5) Écrivez la configuration RedisCacheConfig ; class; Cache Il existe plusieurs classes principales à implémenter : l'une est le gestionnaire de cache CacheManager ; la seconde est la classe d'implémentation d'opération spécifique, la troisième est la classe d'usine CacheManager (elle peut être injectée à l'aide du fichier de configuration ; configuration, ou peut être implémenté via le codage) ); La quatrième est la stratégie de production de clé de cache (bien sûr, Spring est livré avec sa propre stratégie de génération, mais lorsqu'elle est vue sur le client Redis, il s'agit d'une clé sérialisée, qui semble brouillée à nos yeux). yeux. Ici, nous utilisons d’abord la stratégie intégrée).
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:port pairs #spring.redis.sentinel.nodes= ######################################################## ### Java Persistence Api 自动进行建表 ######################################################## # Specify the DBMS spring.jpa.database = MYSQL # Show or not log for each sql query 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 to the entity manager) spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5DialectLe code ci-dessus contient des commentaires très détaillés, mais ici il est brièvement mentionné : RedisCacheConfig n'a pas besoin d'être hérité ici : CachingConfigurerSupport, c'est-à-dire, utilisez simplement une classe ordinaire. Okay ; l'essentiel ici est que nous devons réimplémenter la stratégie de génération de clé plus tard. Tant que le KeyGenerator est modifié ici, il prendra effet sans modification dans d'autres emplacements. Si vous utilisez la méthode de classe ordinaire, vous devez également spécifier le nom du KeyGenerator lors de l'utilisation de @Cacheable, ce qui est plus gênant lors du codage ;
com.kfit.config/RedisCacheConfig: package com.kfit.config; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; import org.springframework.cache.annotation.EnableCaching; 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; /** * redis 缓存配置; * * 注意:RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了; * * 这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。 * * 普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Configuration @EnableCaching//启用缓存,这个注解很重要; publicclass RedisCacheConfig extends CachingConfigurerSupport { /** * 缓存管理器. * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cacheManager = new RedisCacheManager(redisTemplate); returncacheManager; } /** * redis模板操作类,类似于jdbcTemplate的一个类; * * 虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活; * * 这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们 * * 自己的缓存类,比如:RedisStorage类; * * @param factory : 通过Spring进行注入,参数在application.properties进行配置; * @return */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> 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; } }(6) Écrivez une classe d'entité de test DemoInfo
Écrivez une classe d'entité de test : 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(QQ:412887952) * @version v.0.1 */ @Entity publicclass DemoInfo implements Serializable{ privatestaticfinallongserialVersionUID = 1L; @Id@GeneratedValue privatelongid; private String name; private String pwd; publiclong getId() { returnid; } publicvoid setId(longid) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public String getPwd() { returnpwd; } publicvoid setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return"DemoInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + "]"; } }(8) Écrivez la classe DemoInfoService Écrivez le DemoInfoService ; deux aspects techniques ici. , le premier consiste à utiliser l'annotation Spring @Cacheable et l'objet RedisTemplate pour fonctionner. Le code spécifique est le suivant :
com.kfit.repository.DemoInfoRepository: package com.kfit.repository; import org.springframework.data.repository.CrudRepository; import com.kfit.bean.DemoInfo; /** * DemoInfo持久化类 * @author Angel(QQ:412887952) * @version v.0.1 */ publicinterface DemoInfoRepository extends CrudRepository<DemoInfo,Long> { }
com.kfit.service.DemoInfoService:
(9) Écrivez la classe DemoInfoController ;
(10) Testez si le code s'exécute normalementpackage com.kfit.service; import com.kfit.bean.DemoInfo; /** * demoInfo 服务接口 * @author Angel(QQ:412887952) * @version v.0.1 */ publicinterface DemoInfoService { public DemoInfo findById(longid); publicvoid deleteFromCache(longid); void test(); } com.kfit.service.impl.DemoInfoServiceImpl: package com.kfit.service.impl; import javax.annotation.Resource; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import com.kfit.bean.DemoInfo; import com.kfit.repository.DemoInfoRepository; import com.kfit.service.DemoInfoService; /** * *DemoInfo数据处理类 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Service publicclass DemoInfoServiceImpl implements DemoInfoService { @Resource private DemoInfoRepository demoInfoRepository; @Resource private RedisTemplate<String,String> redisTemplate; @Override publicvoid test(){ ValueOperations<String,String> valueOperations = redisTemplate.opsForValue(); valueOperations.set("mykey4", "random1="+Math.random()); System.out.println(valueOperations.get("mykey4")); } //keyGenerator="myKeyGenerator" @Cacheable(value="demoInfo") //缓存,这里没有指定key. @Override public DemoInfo findById(longid) { System.err.println("DemoInfoServiceImpl.findById()=========从数据库中进行获取的....id="+id); returndemoInfoRepository.findOne(id); } @CacheEvict(value="demoInfo") @Override publicvoid deleteFromCache(longid) { System.out.println("DemoInfoServiceImpl.delete().从缓存中删除."); } }Démarrez l'application et accédez à l'adresse : 127.0.0.1:8080. /test
package com.kfit.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.kfit.bean.DemoInfo; import com.kfit.service.DemoInfoService; /** * 测试类. * @author Angel(QQ:412887952) * @version v.0.1 */ @Controller publicclass DemoInfoController { @Autowired DemoInfoService demoInfoService; @RequestMapping("/test") public@ResponseBody String test(){ DemoInfo 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 String test1(){ demoInfoService.test(); System.out.println("DemoInfoController.test1()"); return"ok"; } }
Voir la console Vous pouvez voir :
loaded=DemoInfo [id=1, name=张Three, pwd=123456]
cached=DemoInfo [id=1, name=Zhang San, pwd=123456]DemoInfoServiceImpl.findById()===== ===== Obtenu à partir de la base de données. ...id=2
loaded2=DemoInfo [id=2, name=Zhang San, pwd=123456]
Si vous voyez les informations d'impression ci-dessus, alors le cache est réussi.
Adresse d'accès : 127.0.0.1:8080/test1
random1=0.9985031320746356
DemoInfoController.test1()
loaded=DemoInfo [id=1, name=Zhang San, pwd=123456]
loaded2=DemoInfo [id=2, name=Zhang San, pwd=123456]
À l'heure actuelle, toutes les données sont mises en cache.
À ce moment, effectuez l'action de suppression : 127.0.0.1:8080/delete?id=1
Puis visitez : 127.0.0.1:8080/test
loaded=DemoInfo [id=1, name=Zhang San, pwd=123456]
cached =DemoInfo [id=1, name=张三, pwd=123456]loaded2=DemoInfo [id=2, name=张三, pwd=123456]
(11) Personnalisation Clé de cache ;
在com.kfit.config.RedisCacheConfig类中重写CachingConfigurerSupport中的keyGenerator ,具体实现代码如下:
/** * 自定义key. * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { System.out.println("RedisCacheConfig.keyGenerator()"); returnnew KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { // This will generate a unique key of the class name, the method name //and all method parameters appended. StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } System.out.println("keyGenerator=" + sb.toString()); returnsb.toString(); } }; }
这时候在redis的客户端查看key的话还是序列化的肉眼看到就是乱码了,那么我改变key的序列方式,这个很简单,redis底层已经有具体的实现类了,我们只需要配置下:
//key序列化方式;(不然会出现乱码;),但是如果方法上有Long等非String类型的话,会报类型转换错误; //所以在没有自己定义key生成策略的时候,以下这个代码建议不要这么写,可以不配置或者自己实现ObjectRedisSerializer //或者JdkSerializationRedisSerializer序列化方式; RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long类型不可以会出现异常信息; redisTemplate.setKeySerializer(redisSerializer); redisTemplate.setHashKeySerializer(redisSerializer);
综上以上分析:RedisCacheConfig类的方法调整为:
package com.kfit.config; import java.lang.reflect.Method; import org.springframework.cache.CacheManager; 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.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * redis 缓存配置; * * 注意:RedisCacheConfig这里也可以不用继承:CachingConfigurerSupport,也就是直接一个普通的Class就好了; * * 这里主要我们之后要重新实现 key的生成策略,只要这里修改KeyGenerator,其它位置不用修改就生效了。 * * 普通使用普通类的方式的话,那么在使用@Cacheable的时候还需要指定KeyGenerator的名称;这样编码的时候比较麻烦。 * * @author Angel(QQ:412887952) * @version v.0.1 */ @Configuration @EnableCaching//启用缓存,这个注解很重要; publicclass RedisCacheConfig extends CachingConfigurerSupport { /** * 缓存管理器. * @param redisTemplate * @return */ @Bean public CacheManager cacheManager(RedisTemplate<?,?> redisTemplate) { CacheManager cacheManager = new RedisCacheManager(redisTemplate); returncacheManager; } /** * RedisTemplate缓存操作类,类似于jdbcTemplate的一个类; * * 虽然CacheManager也能获取到Cache对象,但是操作起来没有那么灵活; * * 这里在扩展下:RedisTemplate这个类不见得很好操作,我们可以在进行扩展一个我们 * * 自己的缓存类,比如:RedisStorage类; * * @param factory : 通过Spring进行注入,参数在application.properties进行配置; * @return */ @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, String> 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; } /** * 自定义key. * 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key,即使@Cacheable中的value属性一样,key也会不一样。 */ @Override public KeyGenerator keyGenerator() { System.out.println("RedisCacheConfig.keyGenerator()"); returnnew KeyGenerator() { @Override public Object generate(Object o, Method method, Object... objects) { // This will generate a unique key of the class name, the method name //and all method parameters appended. StringBuilder sb = new StringBuilder(); sb.append(o.getClass().getName()); sb.append(method.getName()); for (Object obj : objects) { sb.append(obj.toString()); } System.out.println("keyGenerator=" + sb.toString()); returnsb.toString(); } }; } }
这时候在访问地址: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下节进行简单的介绍,这节的东西实在是太多了,到这里就打住吧,剩下的就需要靠你们自己进行扩展了。
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!