1.依赖
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>restful</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restful</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>8.0.11</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--Ehcache2.x缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.添加缓存配置文件,在rsource目录下添加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="10000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="1800"
timeToLiveSeconds="259200"
/>
<cache
name="book_cache"
eternal="true"
maxElementsInMemory="5000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="1800"
timeToLiveSeconds="1800"
/>
</ehcache>
4.启动类开启缓存
@SpringBootApplication
@EnableCaching //开启缓存
public class RestfulApplication {
public static void main(String[] args) {
SpringApplication.run(RestfulApplication.class, args);
}
}
5.创建BookDao
package com.example.restful.dao;
import com.example.restful.component.MyKeyGenerator;
import com.example.restful.entity.Book;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
/**
* @CacheConfig:指明使用的缓存的名字,这个配置可选,若不使用
* @CacheConfig注解,则直接在@Cacheable注解中指明缓存名字
*/
@Repository
@CacheConfig(cacheNames = "book_cache")
public class BookDao {
@Autowired
MyKeyGenerator myKeyGenerator;
/**
* @Cacheable:对该方法进行缓存,默认情况下缓存的key是方法的参数
* 缓存的value是方法的返回值。当开发者在其他类中调用该方法时,首先会根据调用参数
* 查看缓存中是否有相关的数据,若有,则直接使用缓存数据,该方法不会执行,
* 否则执行该方法,执行成功后将返回值缓存起来,但若是在当前类中调用该方法,则缓存不会生效
* @Cacheable注解中还有一个属性condition用来描述缓存的执行时机,例如
* @Cacheable(condition = "#id%2==0")表示当id对2取模为0时才进行缓存,否则不缓存
* @param id
* @return
*/
@Cacheable
public Book getBookById(Integer id){
System.out.println("getBookById");
Book book = new Book();
book.setId(id);
book.setName("花姑娘");
book.setAuthor("日本");
return book;
}
/**
* 不如不想用默认的key,也可以@CachePut(key = "#book.id")这样指定缓存的key为参数book对象中的id
* @param book
* @return
*/
@CachePut(key = "#book.id")
public Book updateBookById(Book book){
System.out.println("updateBookById");
book.setName("花花花刚刚");
return book;
}
/**
* @CacheEvict(key = "#id")表示缓存的key为参数id
* @param id
*/
@CacheEvict(key = "#id")
public void deleteBookById(Integer id){
System.out.println("deleteBookById");
}
}
实体类
package com.example.restful.entity;
import java.io.Serializable;
/**
* 实现Serializable接口为了序列化
*/
public class Book implements Serializable {
private Integer id;
private String name;
private String author;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
}
package com.example.restful.component;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* 自定义缓存key的生成器KeyGenerator
*/
@Component
public class MyKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object o, Method method, Object... objects) {
return Arrays.toString(objects);
}
}
创建测试类
@RunWith(SpringRunner.class)
@SpringBootTest
public class RestfulApplicationTests {
@Autowired
BookDao bookDao;
@Test
public void contextLoads() {
bookDao.getBookById(1);
bookDao.getBookById(1); //没有打印因为使用了缓存
bookDao.deleteBookById(1);
Book b3 = bookDao.getBookById(1);
System.out.println("b3:" + b3);
Book b = new Book();
b.setName("不挂鸡");
b.setId(1);
b.setAuthor("鸡你太美");
bookDao.updateBookById(b);
Book b4 = bookDao.getBookById(1);
System.out.println("b4:" + b4);
}
}
自己的结果,因为自己查询了两次,导致前两次查询都是走的缓存,所以没有打印
"C:\Program Files\Java\jdk1.8.0_112\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:D:\idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar=54601:D:\idea\IntelliJ IDEA 2018.2.4\bin" -Dfile.encoding=UTF-8 -classpath "D:\idea\IntelliJ IDEA 2018.2.4\lib\idea_rt.jar;D:\idea\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit-rt.jar;D:\idea\IntelliJ IDEA 2018.2.4\plugins\junit\lib\junit5-rt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_112\jre\lib\rt.jar;F:\gitsource\guns\stylefeng-guns-master\comprehensive\restful\target\test-classes;F:\gitsource\guns\stylefeng-guns-master\comprehensive\restful\target\classes;D:\m2_repository\org\springframework\boot\spring-boot-starter-web\2.1.9.RELEASE\spring-boot-starter-web-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter\2.1.9.RELEASE\spring-boot-starter-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot\2.1.9.RELEASE\spring-boot-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-autoconfigure\2.1.9.RELEASE\spring-boot-autoconfigure-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-logging\2.1.9.RELEASE\spring-boot-starter-logging-2.1.9.RELEASE.jar;D:\m2_repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\m2_repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\m2_repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;D:\m2_repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;D:\m2_repository\org\slf4j\jul-to-slf4j\1.7.28\jul-to-slf4j-1.7.28.jar;D:\m2_repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;D:\m2_repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-json\2.1.9.RELEASE\spring-boot-starter-json-2.1.9.RELEASE.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-databind\2.9.9.3\jackson-databind-2.9.9.3.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\m2_repository\com\fasterxml\jackson\core\jackson-core\2.9.9\jackson-core-2.9.9.jar;D:\m2_repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.9\jackson-datatype-jdk8-2.9.9.jar;D:\m2_repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.9\jackson-datatype-jsr310-2.9.9.jar;D:\m2_repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.9\jackson-module-parameter-names-2.9.9.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-tomcat\2.1.9.RELEASE\spring-boot-starter-tomcat-2.1.9.RELEASE.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.26\tomcat-embed-core-9.0.26.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.26\tomcat-embed-el-9.0.26.jar;D:\m2_repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.26\tomcat-embed-websocket-9.0.26.jar;D:\m2_repository\org\hibernate\validator\hibernate-validator\6.0.17.Final\hibernate-validator-6.0.17.Final.jar;D:\m2_repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;D:\m2_repository\org\jboss\logging\jboss-logging\3.3.3.Final\jboss-logging-3.3.3.Final.jar;D:\m2_repository\com\fasterxml\classmate\1.4.0\classmate-1.4.0.jar;D:\m2_repository\org\springframework\spring-web\5.1.10.RELEASE\spring-web-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-beans\5.1.10.RELEASE\spring-beans-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-webmvc\5.1.10.RELEASE\spring-webmvc-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-aop\5.1.10.RELEASE\spring-aop-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-context\5.1.10.RELEASE\spring-context-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-expression\5.1.10.RELEASE\spring-expression-5.1.10.RELEASE.jar;D:\m2_repository\mysql\mysql-connector-java\8.0.17\mysql-connector-java-8.0.17.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-test\2.1.9.RELEASE\spring-boot-starter-test-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-test\2.1.9.RELEASE\spring-boot-test-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\boot\spring-boot-test-autoconfigure\2.1.9.RELEASE\spring-boot-test-autoconfigure-2.1.9.RELEASE.jar;D:\m2_repository\com\jayway\jsonpath\json-path\2.4.0\json-path-2.4.0.jar;D:\m2_repository\net\minidev\json-smart\2.3\json-smart-2.3.jar;D:\m2_repository\net\minidev\accessors-smart\1.2\accessors-smart-1.2.jar;D:\m2_repository\org\ow2\asm\asm\5.0.4\asm-5.0.4.jar;D:\m2_repository\junit\junit\4.12\junit-4.12.jar;D:\m2_repository\org\assertj\assertj-core\3.11.1\assertj-core-3.11.1.jar;D:\m2_repository\org\mockito\mockito-core\2.23.4\mockito-core-2.23.4.jar;D:\m2_repository\net\bytebuddy\byte-buddy\1.9.16\byte-buddy-1.9.16.jar;D:\m2_repository\net\bytebuddy\byte-buddy-agent\1.9.16\byte-buddy-agent-1.9.16.jar;D:\m2_repository\org\objenesis\objenesis\2.6\objenesis-2.6.jar;D:\m2_repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\m2_repository\org\hamcrest\hamcrest-library\1.3\hamcrest-library-1.3.jar;D:\m2_repository\org\skyscreamer\jsonassert\1.5.0\jsonassert-1.5.0.jar;D:\m2_repository\com\vaadin\external\google\android-json\0.0.20131108.vaadin1\android-json-0.0.20131108.vaadin1.jar;D:\m2_repository\org\springframework\spring-core\5.1.10.RELEASE\spring-core-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-jcl\5.1.10.RELEASE\spring-jcl-5.1.10.RELEASE.jar;D:\m2_repository\org\springframework\spring-test\5.1.10.RELEASE\spring-test-5.1.10.RELEASE.jar;D:\m2_repository\org\xmlunit\xmlunit-core\2.6.3\xmlunit-core-2.6.3.jar;D:\m2_repository\org\springframework\boot\spring-boot-starter-cache\2.1.9.RELEASE\spring-boot-starter-cache-2.1.9.RELEASE.jar;D:\m2_repository\org\springframework\spring-context-support\5.1.10.RELEASE\spring-context-support-5.1.10.RELEASE.jar;D:\m2_repository\net\sf\ehcache\ehcache\2.10.6\ehcache-2.10.6.jar;D:\m2_repository\org\slf4j\slf4j-api\1.7.28\slf4j-api-1.7.28.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 com.example.restful.RestfulApplicationTests
17:32:37.735 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.example.restful.RestfulApplicationTests]
17:32:37.750 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
17:32:37.750 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
17:32:37.766 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.example.restful.RestfulApplicationTests] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
17:32:37.782 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.example.restful.RestfulApplicationTests], using SpringBootContextLoader
17:32:37.782 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.restful.RestfulApplicationTests]: class path resource [com/example/restful/RestfulApplicationTests-context.xml] does not exist
17:32:37.782 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.restful.RestfulApplicationTests]: class path resource [com/example/restful/RestfulApplicationTestsContext.groovy] does not exist
17:32:37.782 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.example.restful.RestfulApplicationTests]: no resource found for suffixes {-context.xml, Context.groovy}.
17:32:37.782 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.example.restful.RestfulApplicationTests]: RestfulApplicationTests does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
17:32:37.844 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.example.restful.RestfulApplicationTests]
17:32:37.938 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [F:\gitsource\guns\stylefeng-guns-master\comprehensive\restful\target\classes\com\example\restful\RestfulApplication.class]
17:32:37.954 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.example.restful.RestfulApplication for test class com.example.restful.RestfulApplicationTests
17:32:38.063 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.example.restful.RestfulApplicationTests]: using defaults.
17:32:38.063 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
17:32:38.079 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
17:32:38.079 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Skipping candidate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener] due to a missing dependency. Specify custom listener classes or make the default listener classes and their required dependencies available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
17:32:38.079 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@703580bf, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@3e92efc3, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@1622f1b, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@72a7c7e0, org.springframework.test.context.support.DirtiesContextTestExecutionListener@2e4b8173, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@70e8f8e, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@17046283, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@5bd03f44, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@29626d54, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@5a63f509]
17:32:38.079 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.restful.RestfulApplicationTests]
17:32:38.079 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.restful.RestfulApplicationTests]17:32:38.079 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.restful.RestfulApplicationTests]
17:32:38.079 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.restful.RestfulApplicationTests]17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.restful.RestfulApplicationTests]
17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.restful.RestfulApplicationTests]
17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.restful.RestfulApplicationTests]
17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.restful.RestfulApplicationTests]
17:32:38.094 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@3c407114 testClass = RestfulApplicationTests, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@35ef1869 testClass = RestfulApplicationTests, locations = '{}', classes = '{class com.example.restful.RestfulApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@887af79, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@6e0e048a, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@63e2203c, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@7f13d6e], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true]], class annotated with @DirtiesContext [false] with mode [null].
17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.restful.RestfulApplicationTests]
17:32:38.094 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.restful.RestfulApplicationTests]
17:32:38.125 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=-1}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.9.RELEASE)
2019-10-14 17:32:38.658 INFO 2368 --- [ main] c.e.restful.RestfulApplicationTests : Starting RestfulApplicationTests on DESKTOP-3NP6QV0 with PID 2368 (started by user in F:\gitsource\guns\stylefeng-guns-master\comprehensive\restful)
2019-10-14 17:32:38.658 INFO 2368 --- [ main] c.e.restful.RestfulApplicationTests : No active profile set, falling back to default profiles: default
2019-10-14 17:32:40.955 INFO 2368 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-10-14 17:32:41.314 WARN 2368 --- [ main] n.sf.ehcache.config.CacheConfiguration : Cache 'book_cache' is set to eternal but also has TTI/TTL set. To avoid this warning, clean up the config removing conflicting values of eternal, TTI and TTL. Effective configuration for Cache 'book_cache' will be eternal='true', timeToIdleSeconds='0', timeToLiveSeconds='0'.
2019-10-14 17:32:41.783 INFO 2368 --- [ main] c.e.restful.RestfulApplicationTests : Started RestfulApplicationTests in 3.658 seconds (JVM running for 4.608)
getBookById
deleteBookById
getBookById
b3:Book{id=1, name='花姑娘', author='日本'}
updateBookById
b4:Book{id=1, name='花花花刚刚', author='小本本'}
2019-10-14 17:32:42.064 INFO 2368 --- [ Thread-4] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'