整合之道--Spring4整合Ehcache2.10 - Go语言中文社区

整合之道--Spring4整合Ehcache2.10


1 写在前面的话

整合思路

Spring与其他框架的整合一般的思路就是将其他框架当作Spring的Bean管理起来,一般会由Spring提供该bean的基本实现,用户只需配置即可。

配置中主要告诉Spring需要整合的是什么东西,怎么实现,有些Spring有对应的实现,Spring没有实现的只需实现Spring的相应接口,然后配置一下就OK了,需要加载配置文件的再告诉Spring配置文件的路径即可。

spring与hibernate的整合就是将hibernate的sessionFactory当作一个bean由spring配置起来,其具体对应实现为org.springframework.orm.hibernate5.LocalSessionFactoryBean(Hibernate5的Spring实现

关于hibernate的整合参见

spring整合hibernate

Spring整合Ehcache也就是将Ehcache中最核心的CacheManager和Cache交由Spring来管理,在Spring看来也就是两个Bean

2 Ehcache安装

首先看一下如何单独的使用Ehcache

Ehcache请参考官方

http://www.ehcache.org/generated/2.10.1/html/ehc-all/

从官方的介绍可知,Ehcache的安装步骤如下

这里写图片描述

1. 下载Ehcache(依赖SLF4J,所以也要下载SLF4J),并将其放在classpath中
2. 配置ehcache.xml文件,并将其放在classpath中

本文选择的版本为Ehcache2.10.0

mavan依赖如下

    <!--ehcache -->
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>2.10.0</version>
    </dependency>
    <!--ehcache-->

    <!--ehcache依赖slf4j-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.18</version>
    </dependency>
    <!--ehcache依赖slf4j-->

    <!--slf4j需要log4j-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.18</version>
    </dependency>
    <!--slf4j需要log4j-->

    <!--log4j-->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.5</version>
    </dependency>
    <!--log4j-->

日志配置如下
log4j.properties

#---------------------------------------------------------
# Log4J Settings for log4j 1.2.x (via jakarta-commons-logging)
#
# The five logging levels used by Log are (in order):
#
#   1. DEBUG (the least serious)
#   2. INFO
#   3. WARN
#   4. ERROR
#   5. FATAL (the most serious)
#
#---------------------------------------------------------
# 日志输出级别
#---------------------------------------------------------
log4j.rootLogger=debug, stdout, info_log, error_log

#---------------------------------------------------------
# 输出到控制台
#---------------------------------------------------------
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
#log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout=org.apache.log4j.TTCCLayout

#---------------------------------------------------------
# info_log
#---------------------------------------------------------
log4j.appender.info_log=org.apache.log4j.DailyRollingFileAppender
log4j.appender.info_log.File=/usr/logs/SpringCache/info.log
log4j.appender.info_log.Append=true
log4j.appender.info_log.Threshold=INFO
log4j.appender.info_log.layout=org.apache.log4j.PatternLayout
log4j.appender.info_log.DatePattern='.'yyyy-MM-dd
log4j.appender.info_log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss:SSS} %p [%M] %c %L %m%n

#---------------------------------------------------------
# error_log
#---------------------------------------------------------
log4j.appender.error_log=org.apache.log4j.DailyRollingFileAppender
log4j.appender.error_log.File=/usr/logs/SpringCache/error.log
log4j.appender.error_log.Append=true
log4j.appender.error_log.Threshold=ERROR
log4j.appender.error_log.layout=org.apache.log4j.PatternLayout
log4j.appender.error_log.DatePattern='.'yyyy-MM-dd
log4j.appender.error_log.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss:SSS} %p [%M] %c %L %m%n

Ehcache的配置文件如下

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <defaultCache
            maxEntriesLocalHeap="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskSpoolBufferSizeMB="30"
            maxEntriesLocalDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>

    <cache name="sampleCache1"
           maxEntriesLocalHeap="10000"
           maxEntriesLocalDisk="1000"
           eternal="false"
           diskSpoolBufferSizeMB="20"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
        <persistence strategy="localTempSwap"/>
    </cache>

</ehcache>

ehcache.xml中的配置来自Ehcache官方下载包中的exchache.xml片段。

这里写图片描述

按照官方说明运行Ehcache示例

Ehcache测试程序

package com.gwc.springlearn;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.junit.Test;

/**
 * Created by GWCheng on 2016/3/4.
 */
public class TestEhcache {
    @Test
    public void testEhcache() {
        // Creating a CacheManager based on a specified configuration file.
        CacheManager manager = CacheManager.newInstance("src/main/resources/ehcache.xml");
        // obtains a Cache called sampleCache1, which has been preconfigured in the configuration file
        Cache cache = manager.getCache("sampleCache1");
        // puts an element into a cache
        Element element = new Element("key1", "哈哈");
        cache.put(element);
        //The following gets a NonSerializable value from an element with a key of key1.
        Object value = element.getObjectValue();
        System.out.println(value.toString());
        manager.shutdown();
    }
}

运行结果

这里写图片描述

本文并不是要详细讲解Ehcache的用法,本文只是通过Ehcache的使用了解其用法,以方便与Spring整合。

3 与Spring整合

Ehcache核心类

这里写图片描述

从官方的介绍来看,Ehcache的核心包括CacheManager、Cache和Element

CacheManager

The CacheManager class is used to manage caches. Creation of, access to, and removal of caches is controlled by a named CacheManager.

CacheManager是Ehcache的核心,CacheManager来管理对cache的创建,访问和移除操作。

Cache

A Cache is a thread-safe logical representation of a set of data elements, analogous to a cache region in many caching systems.

Cache是一个线程安全的数据集合的逻辑表示,是它就是缓存。

Element

An element is an atomic entry in a cache.

可以理解为缓存中的key-value形式的元素。在程序中通常将需要缓存的对象放在Element中,整合的时候不会用到。

回顾一下Spring中的抽象缓存

参考Spring抽象缓存

http://blog.csdn.net/frankcheng5143/article/details/50791757

我们发现Spring对缓存的整合,主要是将CacheManager和Cache分别用Bean配置

通过上面的分析我们知道Ehcache的核心也是CacheManagerCache

回顾一下Spring对JDK ConcurrentMap-based Cach的配置

<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches">
        <set>
            <!-- 默认的缓存 -->
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
            <!-- 例子中一直使用的"books",也就是那个cacheNames="books" -->
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
        </set>
    </property>
</bean>

那么Spring对Ehcache的整合也就非常简单了,将Ehcache的CacheManage和Cache分别交给Spring管理就ok了。

Spring整合Ehcache的配置文件

核心配置如下

<bean id="cacheManager"
          class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>

    <!-- EhCache library setup -->
    <bean id="ehcache"
          class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="ehcache.xml"/>

ehcache.xml仍然采用上面的配置

完整的缓存配置spring-ehcache.xml如下

spring-ehcache.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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd
        http://www.springframework.org/schema/cache
        http://www.springframework.org/schema/cache/spring-cache-4.2.xsd">

    <context:component-scan base-package="com.gwc.springlearn"/>
    <cache:annotation-driven/>


    <bean id="cacheManager"
          class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache"/>

    <!-- EhCache library setup -->
    <bean id="ehcache"
          class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="ehcache.xml"/>
</beans>

4 测试

为了测试的一致性,采用和 Spring文档学习–缓存(Cache Abstraction)
相同的测试用例

项目结构

这里写图片描述

整合之后的maven依赖

     <dependencies>

        <!--spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <!--spring -->

        <!--ehcache -->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.0</version>
        </dependency>
        <!--ehcache-->

        <!--ehcache依赖slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.18</version>
        </dependency>
        <!--ehcache依赖slf4j-->

        <!--slf4j需要log4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.18</version>
        </dependency>
        <!--slf4j需要log4j-->

        <!--log4j-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.5</version>
        </dependency>
        <!--log4j-->

        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--junit-->
    </dependencies>

因为Spring文档学习–缓存(Cache Abstraction)中的缓存名字为“books”,所以修改ehcache.xml的name为“books”

如下

 <cache name="books"
           maxEntriesLocalHeap="10000"
           maxEntriesLocalDisk="1000"
           eternal="false"
           diskSpoolBufferSizeMB="20"
           timeToIdleSeconds="300"
           timeToLiveSeconds="600"
           memoryStoreEvictionPolicy="LFU"
           transactionalMode="off">
        <persistence strategy="localTempSwap"/>
    </cache>

运行测试用例,测试用例参考Spring文档学习–缓存(Cache Abstraction)

因为启动或者关闭程序缓存并没有关闭,所以为了测试,在运行之前需要清空缓存。而且这次需要加载spring-ehcache.xml

@ContextConfiguration(locations = {"classpath:spring-ehcache.xml"})

在测试用例中添加如下代码

    @Before
    public void init(){
        cacheService.loadBooks();
    }

被测试的CacheService不变,CacheService参考Spring文档学习–缓存(Cache Abstraction)

测试@Cacheable

 @Test
    public void testCacheable() throws BookNotFoundException {

        Book book = null;
        for (int i = 0; i < 10; i++) {
            book = cacheService.findBook("123");
        }

        cacheService.findBook("456");
        cacheService.findBook("456");
        cacheService.findBook("456");
    }

运行报错如下

ERROR net.sf.ehcache.store.disk.DiskStorageFactory - Disk Write of 456 failed: 
java.io.NotSerializableException: com.gwc.springlearn.Book

Ehcache被缓存的对象需要实现Serializable接口

修改Book.java

public class Book implements Serializable{
    //省略,参考http://blog.csdn.net/frankcheng5143/article/details/50791757
}

继续执行

这里写图片描述

说明已经讲Ehcache整合到了Spring中。

关于其他方法的测试参考

http://blog.csdn.net/frankcheng5143/article/details/50791757

参考文献

http://www.ehcache.org/generated/2.9.0/pdf/Ehcache_API_Developer_Guide.pdf
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/
http://blog.csdn.net/frankcheng5143/article/details/50791757

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/frankcheng5143/article/details/50776542
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 22:49:00
  • 阅读 ( 1765 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢