1. 程式人生 > >spring中添加google的guava緩存(demo)

spring中添加google的guava緩存(demo)

-m map() lee dem 方法 onf map truct site

1.pom文件中配置

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency
> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <
artifactId>guava</artifactId> <version>19.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency
> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.20</version> </dependency> </dependencies>

2.GuavaCacheManagerConfig配置類

package com.zy;

import com.google.common.cache.CacheBuilder;
import com.google.common.collect.Maps;
import org.springframework.cache.Cache;
import org.springframework.cache.guava.GuavaCache;
import org.springframework.cache.transaction.AbstractTransactionSupportingCacheManager;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;

public class GuavaCacheManagerConfig extends AbstractTransactionSupportingCacheManager {

    private final ConcurrentMap<String, Cache> cacheMap = Maps.newConcurrentMap();
    private Map<String, CacheBuilder> builderMap = Maps.newHashMap();

    @Override
    protected Collection<? extends Cache> loadCaches() {
        return cacheMap.values();
    }

    //獲取緩存單例
    @Override
    public Cache getCache(String name) {
        Cache cache = this.cacheMap.get(name);
        if (null == cache) {
            synchronized (this.cacheMap) {
                cache = this.cacheMap.get(name);
                if (null == cache && this.builderMap.containsKey(name)) {
                    CacheBuilder builder = this.builderMap.get(name);
                    cache = createGuavaCache(name, builder);
                    this.cacheMap.put(name, cache);
                }
            }
        }
        return cache;
    }

    private Cache createGuavaCache(String name, CacheBuilder builder) {
        com.google.common.cache.Cache<Object, Object> cache;
        if(builder == null){
            cache = CacheBuilder.newBuilder().build();
        }else{
            cache = builder.build();
        }
        return new GuavaCache(name, cache, isAllowNullValues());
    }


    private boolean isAllowNullValues() {
        return true;
    }

    //配置中多組緩存池註入
    public void setConfigMap(Map<String, CacheBuilder> configMap) {
        this.builderMap = configMap;
    }
}

3.applicationContext-cache-guava.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/cache
                           http://www.springframework.org/schema/cache/spring-cache.xsd">

    <!-- 1.將需要加入緩存的類註冊進來 -->
    <bean id="guavaService" class="com.zy.GuavaServiceImpl"/>

    <!-- ==========================2.開啟guava緩存開始==================== -->
    <!-- 聲明緩存註解的開啟 -->
    <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
    <!-- 聲明使用spring管理緩存組 -->
    <bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
        <property name="cacheManagers">
            <list>
                <ref bean="guavaCacheManager"/>
            </list>
        </property>
        <property name="fallbackToNoOpCache" value="true"/>
    </bean>
    <!-- 緩存的創建的具體實現類註入 class為自定義的類 -->
    <bean id="guavaCacheManager" class="com.zy.GuavaCacheManagerConfig">
        <!-- 此處可以配置一組緩存池對應不同的業務類型 這裏實現了一個"guava"的默認緩存並構建 -->
        <property name="configMap">
            <map key-type="java.lang.String" value-type="com.google.common.cache.CacheBuilder">
                <!-- 該緩存與service層實現類上註解上的value相等 -->
                <entry key="guava" value-ref="defaultCacheBuilder"/>
            </map>
        </property>
    </bean>

    <!-- 此處直接構建"guava"默認緩存 -->
    <bean id="defaultCacheBuilder"
          class="com.google.common.cache.CacheBuilder"
          factory-method="from">
        <!-- 緩存池大小 時間(定時回收 緩存項在給定時間內沒有被‘寫‘訪問 回收 還有refreshAfterWrite expireAfterAccess可供使用) 當然還有一些其他可選組件(weakKeys,removalListener and so on!) -->
        <constructor-arg value="maximumSize=10000, expireAfterAccess=5s"/>
    </bean>
    <!-- ==========================2.開啟guava緩存結束==================== -->

</beans>

4.GuavaDTO

package com.zy;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class GuavaDTO {

    private Integer id;

    private String name;

}

5.GuavaServiceImpl的實現類

package com.zy;

import org.springframework.cache.annotation.Cacheable;
public class GuavaServiceImpl {
    // spring EL
    // GuavaDTO 普通的DTO
    // @Cacheable(value = "guava", key = "‘testGuavaCache:‘ + #guavaDTO.id + #guavaDTO.name")
    // value 為配置文件中的緩存池名稱 key 為鍵名
    @Cacheable(value = "guava", key = "‘testGuavaCache:‘ + #guavaDTO.id + #guavaDTO.name")
    public void testGuavaCache(GuavaDTO guavaDTO) {
        System.out.println("=======緩存中沒有,進入方法來查詢了=========");
    }

}

技術分享圖片

如果service的實現類是刪除方法,則在方法上,加上@CacheEvict註解

如果service的實現類是更新方法,則在方法上,加上@CachePut註解(每次執行,都會進入方法)

6.測試類GuavaTest

package com.zy;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class GuavaTest {

    @Test
    public void fn() throws InterruptedException {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-cache-guava.xml");
        GuavaServiceImpl guavaService = (GuavaServiceImpl) applicationContext.getBean("guavaService");
        System.out.println("第1次訪問:1號tom==========================");
        guavaService.testGuavaCache(new GuavaDTO(1, "tom"));
        System.out.println("第2次訪問:1號tom==========================");
        guavaService.testGuavaCache(new GuavaDTO(1, "tom"));
        guavaService.testGuavaCache(new GuavaDTO(1, "tom"));
        System.out.println("第1次訪問:2號jerry==========================");
        guavaService.testGuavaCache(new GuavaDTO(2, "jerry"));
        Thread.sleep(5000);
        /**
         * 此時配置文件中的失效時間是5000ms
         * */
        System.out.println("第3次訪問:1號tom==========================");
        guavaService.testGuavaCache(new GuavaDTO(1, "tom"));

    }
}

7.測試結果如下:

技術分享圖片

spring中添加google的guava緩存(demo)