在我们开发中经常碰到一个方法总是执行的很慢,但是这个方法对数据的实时准确度要求不是很高的时候,我们可以使用缓存技术来优化。
开始
首先你的引入这个jar包
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>
接着就是你要告诉配置文件一些基本信息:比如
#cache spring.cache.type=simple spring.cache.cache-names=spm-cache
然后你得让你的springboot知道你要开始使用缓存了
package com.wwx.config; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import org.springframework.beans.factory.annotation.Value; import org.springframework.cache.Cache; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.concurrent.ConcurrentMapCache; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableCaching//我们开启缓存了 public class SimpleCacheConfigurer{ @Bean public SimpleCacheManager simpleCacheManager(){//springboot支持的缓存有很多,我们选择一个最为简单的 SimpleCacheManager s = new SimpleCacheManager(); s.setCaches(Collections.singletonList(new ConcurrentMapCache("people"))); return s; } @Bean public KeyGenerator cacheKeyGenerator(){//缓存key生成者 CacheKeyGenerator cacheKeyGenerator = new CacheKeyGenerator(); return cacheKeyGenerator; } }
下面是keyGenerator的代码
package com.wwx.config; import java.io.UnsupportedEncodingException; import java.lang.reflect.Method; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HashMap; import java.util.Map; import org.apache.tomcat.util.security.MD5Encoder; import org.springframework.cache.interceptor.KeyGenerator; import com.alibaba.fastjson.JSONObject; public class CacheKeyGenerator implements KeyGenerator { @Override public Object generate(Object target, Method method, Object... params) { // TODO Auto-generated method stub Map<String, Object> map = new HashMap<String, Object>(); map.put("target", target.getClass().toGenericString());//放入target的名字 map.put("method", method.getName());//放入method的名字 if (params != null && params.length > 0) {//把所有参数放进去 int i = 0; for (Object o : params) { map.put("params-" + i, o); i++; } } String str = JSONObject.toJSON(map).toString(); byte[] hash = null; String s = null; try { hash = MessageDigest.getInstance("MD5").digest(str.getBytes("UTF-8")); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } s=MD5Encoder.encode(hash);//使用MD5生成位移key return s; } }
最后我们可以这样使用
package com.wwx.service; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.wwx.entity.Person; @Service public class TestService { @CachePut(key="#person.id",value="people") public Person save(Person person){ System.err.println("save person is ok!"); return person; } @Cacheable(key="#id",value="people") public Person findPersonById(Long id){ System.err.println("get one person!"); return new Person(); } //上面的两个方法的代码可以忽略 @Cacheable(keyGenerator="cacheKeyGenerator",value="people") public Person findPersonByFuza(Person person){//这里是比较复杂的查询条件,实际中可能是HashMap之类存在各种参数的东东 System.err.println("go go go go!"); return person; } }
这里简单解释一下@Cachable的使用,
在方法执行前Spring先查看缓存中是否有这个key的数据,如果有数据,则直接返回缓存数据;如果没有数据,调用
方法将返回值放进缓存。
这里我们要注意一点就是几乎所有的缓存支持几乎都要返回值,因为这个是我们给Spring要缓存的数据,试着想一下
如果没有返回值,你缓存个毛线啊。
以上信息部分引用来自《JavaEE开发的颠覆者SpringBoot实战》