spring boot項目中使用redis做爲緩存。java
先建立spring boot的maven工程,在pom.xml中添加依賴node
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>1.5.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.3.8.RELEASE</version> </dependency>
在application.properties中添加配置web
server.port:9000 #服務啓動的端口
spring.redis.database=0 #redis數據庫的索引,默認爲0 spring.redis.host=192.168.133.130 #spring.redis.password= spring.redis.port=6379 spring.redis.pool.max-idle=8 #最大空閒連接數 spring.redis.pool.min-idle=0 #最小空閒鏈接數 spring.redis.pool.max-active=8 #鏈接池最大鏈接數,負數表示無最大鏈接數 spring.redis.pool.max-wait=-1 #鏈接池最大阻塞等待時間,負數表示沒有 #spring.redis.sentinel.master= #主節點 #spring.redis.sentinel.nodes= #
spring.data.mongodb.host=192.168.133.130 spring.data.mongodb.port=27017 spring.data.mongodb.database=fzk
在啓動類中添加註解redis
@SpringBootApplication @EnableCaching
public class Main { public static void main(String[] args) throws Exception { SpringApplication.run(Main.class, args); } }
@EnableCaching會爲每一個bean中被 @Cacheable
, @CachePut
and @CacheEvict修飾的public方法進行緩存操做。
spring
緩存的用法mongodb
@Cacheable(value = "test", key = "'user_'.concat(#root.args[0])") public User getUser(String userId) { System.out.println("in getUser"); User user = new User(); user.setId(userId); user.setPassword("passwd"); user.setUsername("username"); return user; }
這個方法在userId相同形同的狀況下,第一次調用的時候會執行方法,之後每次在調用的時候會讀取緩存中的數據。數據庫
緩存的註解介紹:
@Cacheable
這個註解,會每次先檢查是否執行過這個方法,在從緩存數據庫中查看key是否相等,若是找到了,從緩存中讀取,沒有匹配的那麼執行該方法,將結果緩存。
緩存都是經過key-value進行儲存的,value或cacheNames必須指定(value是cacheNames的別名),指定多個value用(value = {"value1", "value2"})若是沒有指定key,spring會提供一個默認的KeyGenerator,這個KeyGenerator根據參數生成key,若是方法沒有參數返回KeyGenerator.EMPTY,若是有一個參數返回這個實例,若是有多個參數返回包含這些參數的SimpleKey。能夠經過繼承CachingConfigurerSupport本身指定KeyGenerator,類上加@Configuration註解。也能夠像上面那樣本身指定key,須要瞭解SPEL表達式。
多線程的狀況下,可能同時會有多個線程同時進入一個沒被緩存過的方法,這樣會致使多個線程都會執行一遍方法,sync="true"會將第一次計算返回值的這個方法lock,計算完成後將結果緩存緩存
@Cacheable(value="foos", sync="true") public Foo executeExpensiveOperation(String id) {...}
在某些狀況下,可能並不想把結果進行緩存,可經過condition進行篩選多線程
@Cacheable(value="book", condition="#name.length() < 32") public Book findBook(String name)
上面的#root表示的是返回值,其餘一些可用的參數(來自spring官網)app
@CachePut
每次都會執行該方法,並將結果進行緩存。用法與@Cacheable用法一致。
@CacheEvict
用於將清空緩存,能夠指定key, value, condition,這幾個的用法與上面介紹的一致。key和condition能夠爲空,若是爲空,表示用默認策略。
@CacheEvict(value="books", allEntries=true, beforeInvocation=true) public void loadBooks(InputStream batch)
allEntries=true表示清空books下的全部緩存,默認爲false,beforeInvocation=true表示是否在方法執行前就清空緩存,默認爲false。
@Caching
能夠包含上面介紹的三個註解,key-value分別對應(cachable=[@Cacheable], put=[@CachePut], evict=[@CacheEvict])
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") }) public Book importBooks(String deposit, Date date)
@CacheConfig
是一個類級的註解
@CacheConfig("books") public class BookRepositoryImpl implements BookRepository { @Cacheable public Book findBook(ISBN isbn) {...} }
這樣類下的每一個方法的緩存都用的是books,還能夠指定自定義的KeyGenerator和CacheManager。
自定義緩存註解
經過使用上面的註解做爲元直接實現自定義註解
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) @Cacheable(value="books", key="#isbn") public @interface SlowService { }
這樣咱們就能夠直接使用@SlowService做爲註解
@SlowService public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
與下面的註解功能相同
@Cacheable(cacheNames="books", key="#isbn") public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
還有一點上面沒說到的是spring用CacheManager管理緩存
這裏用到的redis,因此確定是用的RedisCacheManager,一樣,咱們也能夠從新配置一下RedisCacheManager,在這裏咱們也能夠配置一些參數,例如過時時間等等。
上面說到過默認的key生成器,咱們一樣能夠定義本身的KeyGenerator,下面是實現
import java.lang.reflect.Method; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurerSupport; 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.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; @Configuration public class RedisConfig extends CachingConfigurerSupport { @Bean public KeyGenerator wiselyKeyGenerator() { return new KeyGenerator() { @Override public Object generate(Object target, Method method, Object... params) { StringBuilder sb = new StringBuilder(); sb.append(target.getClass().getName()); sb.append(method.getName()); for (Object obj : params) { sb.append(obj.toString()); } return sb.toString(); } }; } @Bean public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) { RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate); return cacheManager; } }
生成CacheManager用到的RedisTemplate一樣能夠自定義,這個主要是與redis數據庫鏈接用的