spring boot 集成EHCache

xiaoxiao2021-02-28  156

本章知识点: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文件:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 < 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);

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ######################################################## ###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,具体代码如下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 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配置文件,当然这个文件你可以放在其它目录下:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 <? 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实体类进行缓存测试:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 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:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 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 进行测试,主要是观察控制台的打印信息。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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 ]
转载请注明原文地址: https://www.6miu.com/read-20397.html

最新回复(0)