目录

spring boot 集成EHCache

2018年04月06日 09:22 | 3724次浏览

本章知识点:Spring Data JPA,Spring Boot 使用Mysql,Spring MVC,EHCache,Spring Cache等(其中@Cacheable请看上一节的理论知识),具体分如下几个步骤:

步骤描述
1新建Maven Java Project
2在pom.xml中加入依赖包
3编写Spring Boot启动类;
4配置application.properties;
5编写缓存配置类以及ehcache.xml配置文件
6编写DemoInfo实体类进行测试;
7编写持久类DemoInfoRepository;
8编写处理类DemoInfoService;
9编写DemoInfoController测试类;运行测试

接下来是具体实现

1)新建Maven Java Project

 新建一个工程名为spring-boot-ehcache的maven java project。

(2)在pom.xml中加入依赖包

  在pom.xml文件中加入相应的依赖包,Spring Boot父节点依赖包;spring boot web支持;缓存依赖spring-context-support;集成ehcache需要的依赖;JPA操作数据库;mysql 数据库驱动,具体pom.xml文件:

<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-ehcache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>spring-boot-ehcache</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>
 
       <!-- 集成ehcache需要的依赖-->
       <dependency>
           <groupId>net.sf.ehcache</groupId>
           <artifactId>ehcache</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>
       
        <!-- Spring boot单元测试. -->
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

3)编写Spring Boot启动类(com.kfit.App.java);

package com.kfit;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
/**
 *
 *
 * @SpringBootApplication申明让spring boot自动给程序进行必要的配置,
 *
@SpringBootApplication
等待于:
@Configuration
@EnableAutoConfiguration
@ComponentScan
 *
 * 
 * @version v.0.1
 */
@SpringBootApplication
public class App {
    public static void main(String[] args) {
       SpringApplication.run(App.class, args);
    }
}

(4)配置application.properties;

在application.properties中主要配置数据库连接和JPA的基本配置,具体如下:

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
 
 
 
########################################################
### Java Persistence Api ,JPA自动建表操作配置
########################################################
# 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.MySQL5Dialect

5)编写缓存配置类以及ehcache.xml配置文件:

 这个类主要是注册缓存管理对象EhCacheCacheManager、缓存工厂对象EhCacheManagerFactoryBean,具体代码如下:

package com.kfit.config;
 
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
 
/**
 * 缓存配置.
 * 
 * @version v.0.1
 */
@Configuration
@EnableCaching//标注启动缓存.
public class CacheConfiguration {
   
    /**
     *  ehcache 主要的管理器
     * @param bean
     * @return
     */
    @Bean
    public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean){
       System.out.println("CacheConfiguration.ehCacheCacheManager()");
       return new EhCacheCacheManager(bean.getObject());
    }
   
    /*
       * 据shared与否的设置,
       * Spring分别通过CacheManager.create()
       * 或new CacheManager()方式来创建一个ehcache基地.
       *
       * 也说是说通过这个来设置cache的基地是这里的Spring独用,还是跟别的(如hibernate的Ehcache共享)
       *
       */
      @Bean
      public EhCacheManagerFactoryBean ehCacheManagerFactoryBean(){
        System.out.println("CacheConfiguration.ehCacheManagerFactoryBean()");
        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean ();
        cacheManagerFactoryBean.setConfigLocation (new ClassPathResource("conf/ehcache.xml"));
        cacheManagerFactoryBean.setShared(true);
        return cacheManagerFactoryBean;
      }
   
}

在src/main/resouces/conf下编写ehcache.xml配置文件,当然这个文件你可以放在其它目录下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
    updateCheck="false">
   
   
    <!--
    diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
       user.home – 用户主目录
       user.dir  – 用户当前工作目录
       java.io.tmpdir – 默认临时文件路径
      
     -->
    <diskStore path="java.io.tmpdir/Tmp_EhCache" />
   
    <!--
       defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
     -->
     
     <!--
       name:缓存名称。
       maxElementsInMemory:缓存最大数目
       maxElementsOnDisk:硬盘最大缓存个数。 
       eternal:对象是否永久有效,一但设置了,timeout将不起作用。 
       overflowToDisk:是否保存到磁盘,当系统当机时
       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. 
       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 
       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 
        clearOnFlush:内存数量最大时是否清除。
         memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
            FIFO,first in first out,这个是大家最熟的,先进先出。
            LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
            LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
    -->
    <defaultCache
       eternal="false"
       maxElementsInMemory="1000"
       overflowToDisk="false"
       diskPersistent="false"
       timeToIdleSeconds="0"
       timeToLiveSeconds="600"
       memoryStoreEvictionPolicy="LRU" />
 
    <cache
       name="demo"  
       eternal="false"
       maxElementsInMemory="100"
       overflowToDisk="false"
       diskPersistent="false"
       timeToIdleSeconds="0"
       timeToLiveSeconds="300"
       memoryStoreEvictionPolicy="LRU" />
      
</ehcache>

(6)编写DemoInfo实体类进行测试;

在com.kfit.bean下编写DemoInfo实体类进行缓存测试:

package com.kfit.bean;
 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
 
/**
 * 测试实体类.
 
 * @version v.0.1
 */
@Entity
public class DemoInfo {
    @Id @GeneratedValue
    private longid;//主键.
    private String name;//名称;
    private String pwd;//密码;
    private intstate;
    public long getId() {
       returnid;
    }
    public void setId(longid) {
       this.id = id;
    }
    public String getName() {
       returnname;
    }
    publicvoid setName(String name) {
       this.name = name;
    }
    public String getPwd() {
       returnpwd;
    }
    public void setPwd(String pwd) {
       this.pwd = pwd;
    }
    public int getState() {
       returnstate;
    }
    public void setState(intstate) {
       this.state = state;
    }
    @Override
    public String toString() {
       return "DemoInfo [id=" + id + ", name=" + name + ", pwd=" + pwd + ", state=" + state + "]";
    }
}

(7)编写持久类DemoInfoRepository;

编写持久类DemoInfoRepository:

com.kfit.repository.DemoInfoRepository:

package com.kfit.repository;
 
import org.springframework.data.repository.CrudRepository;
 
import com.kfit.bean.DemoInfo;
 
/**
 * 操作数据库.
 * 
 * @version v.0.1
 */
public interface DemoInfoRepository extends CrudRepository<DemoInfo,Long>{
 
}

(8)编写处理类DemoInfoService;

编写增删改查的方法,在这几个方法中都使用注解缓存,进行缓存的创建以及删除,修改等操作:

com.kfit.service.DemoInfoService:

package com.kfit.service;
 
import com.kfit.bean.DemoInfo;
 
import javassist.NotFoundException;
 
public interface DemoInfoService {
 
    void delete(Long id);
 
    DemoInfo update(DemoInfo updated) throws NotFoundException;
 
    DemoInfo findById(Long id);
 
    DemoInfo save(DemoInfo demoInfo);
 
}

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.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
 
import com.kfit.bean.DemoInfo;
import com.kfit.repository.DemoInfoRepository;
import com.kfit.service.DemoInfoService;
 
import javassist.NotFoundException;
 
@Service
public class DemoInfoServiceImpl implements DemoInfoService {
   
    //这里的单引号不能少,否则会报错,被识别是一个对象;
    public static final String CACHE_KEY = "'demoInfo'";
  
     @Resource
     private DemoInfoRepository demoInfoRepository;
   
    /**
     * value属性表示使用哪个缓存策略,缓存策略在ehcache.xml
    */
    public static final String DEMO_CACHE_NAME = "demo";
   
    /**
     * 保存数据.
     * @param demoInfo
     */
    @CacheEvict(value=DEMO_CACHE_NAME,key=CACHE_KEY)
    @Override
    public DemoInfo save(DemoInfo demoInfo){
       return demoInfoRepository.save(demoInfo);
    }
   
    /**
     * 查询数据.
     * @param id
     * @return
     */
    @Cacheable(value=DEMO_CACHE_NAME,key="'demoInfo_'+#id")
    @Override
    public DemoInfo findById(Long id){
       System.err.println("没有走缓存!"+id);
       return demoInfoRepository.findOne(id);
    }
   
    /**
     * http://www.mincoder.com/article/2096.shtml:
     *
     * 修改数据.
     *
     * 在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
 
       @CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
     *
     * @param updated
     * @return
     *
     * @throws NotFoundException
     */
    @CachePut(value = DEMO_CACHE_NAME,key = "'demoInfo_'+#updated.getId()")
    //@CacheEvict(value = DEMO_CACHE_NAME,key = "'demoInfo_'+#updated.getId()")//这是清除缓存.
    @Override
    public DemoInfo update(DemoInfo updated) throws NotFoundException{
       DemoInfo demoInfo = demoInfoRepository.findOne(updated.getId());
       if(demoInfo == null){
           thrownew NotFoundException("No find");
       }
       demoInfo.setName(updated.getName());
       demoInfo.setPwd(updated.getPwd());
       return demoInfo;
    }
   
   
    /**
     * 删除数据.
     * @param id
     */
    @CacheEvict(value = DEMO_CACHE_NAME,key = "'demoInfo_'+#id")//这是清除缓存.
    @Override
    public void delete(Long id){
       demoInfoRepository.delete(id);
    }
      
   
}

(9)编写DemoInfoController测试类;

编写一个rest进行测试:

com.kfit.controller.DemoInfoController:

package com.kfit.controller;
 
import javax.annotation.Resource;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import com.kfit.bean.DemoInfo;
import com.kfit.service.DemoInfoService;
 
import javassist.NotFoundException;
 
@RestController
public class DemoInfoController {
 
    @Resource
    private DemoInfoService demoInfoService;
   
    @RequestMapping("/test")
    public String test(){
      
       //存入两条数据.
        DemoInfo demoInfo = new DemoInfo();
        demoInfo.setName("张三");
        demoInfo.setPwd("123456");
        DemoInfo demoInfo2 = demoInfoService.save(demoInfo);
      
        //不走缓存.
        System.out.println(demoInfoService.findById(demoInfo2.getId()));
        //走缓存.
        System.out.println(demoInfoService.findById(demoInfo2.getId()));
       
       
        demoInfo = new DemoInfo();
        demoInfo.setName("李四");
        demoInfo.setPwd("123456");
        DemoInfo demoInfo3 = demoInfoService.save(demoInfo);
       
        //不走缓存.
        System.out.println(demoInfoService.findById(demoInfo3.getId()));
        //走缓存.
        System.out.println(demoInfoService.findById(demoInfo3.getId()));
       
        System.out.println("============修改数据=====================");
        //修改数据.
        DemoInfo updated = new DemoInfo();
        updated.setName("李四-updated");
        updated.setPwd("123456");
        updated.setId(demoInfo3.getId());
        try {
           System.out.println(demoInfoService.update(updated));
       } catch (NotFoundException e) {
           e.printStackTrace();
       }
       
        //不走缓存.
        System.out.println(demoInfoService.findById(updated.getId()));
       
       return "ok";
    }
   
   
}

(10)运行测试;

运行App.java进行测试,访问:http://127.0.0.1:8080/test 进行测试,主要是观察控制台的打印信息。

Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存!52
DemoInfo [id=52, name=张三, pwd=123456, state=0]
DemoInfo [id=52, name=张三, pwd=123456, state=0]
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存!53
DemoInfo [id=53, name=李四, pwd=123456, state=0]
DemoInfo [id=53, name=李四, pwd=123456, state=0]
============修改数据=====================
DemoInfo [id=53, name=李四-updated, pwd=123456, state=0]
DemoInfo [id=53, name=李四-updated, pwd=123456, state=0]
C:\Users\ADMINI~1.ANG\AppData\Local\Temp\
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存!54
DemoInfo [id=54, name=张三, pwd=123456, state=0]
DemoInfo [id=54, name=张三, pwd=123456, state=0]
Hibernate: insert into demo_info (name, pwd, state) values (?, ?, ?)
没有走缓存!55
DemoInfo [id=55, name=李四, pwd=123456, state=0]
DemoInfo [id=55, name=李四, pwd=123456, state=0]
============修改数据=====================
DemoInfo [id=55, name=李四-updated, pwd=123456, state=0]
DemoInfo [id=55, name=李四-updated, pwd=123456, state=0]




小说《我是全球混乱的源头》

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程


上一篇:jquery 选择器 下一篇:css margin外边距
^