近期尝试了一下
SpringBoot 3.3.5
JDK17
Ehcache3.10.8整合
注意,这个版本的boot,提出了公用的缓存模板,Spring官网有相关介绍,整合ehcache需要使用jcache。
老版本的3.0版本以下整合,我这里就不参与了,可以百度自行了解。
废话不多说,直接上Code
Pom文件,(第一坑,Ehcahce3报出xml解析不了,高版本的jdk会出现的jakarta问题,
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/ValidationEventHandler
)
百度可以找到版本问题,但是找不到核心问题。所以没办法只能去啃ehcache3官网:https://www.ehcache.org/documentation/3.10/ ++》https://github.com/ehcache/ehcache3/releases/tag/v3.10.8
去看看Ehcache3的依赖配置:关于如何整入JR107(JCache)
提示到:高版本的jdk需要使用jakarta命名空间做区分,而低版本的则是使用javax.
PS:springboot3源码其实也给了提示:
<?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>3.3.5</version>
</parent>
<groupId>com.tonyjoba</groupId>
<artifactId>SpringBoot_SSM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot3_Ehcache3</name>
<description>整合框架SpringBoot3_Ehcache3</description>
<properties>
<java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!--开启Spring Boot 缓存场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
.......中间的省略,可以根据自己的项目配置
<!-- Ehcache 坐标 -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.10.8</version>
<!--注意如果是用高版本的jdk,需要添加这个,否则会解析不了xml配置文件,类解析器-->
<classifier>jakarta</classifier>
</dependency>
<!--测试场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
全局配置:application.yml
spring:
cache: #配置SpringBoot的缓存,通过统一的缓存模板jcache
type: jcache #jcache 支持 ehcache3 redis等
jcache:
#jcache提供方
provider: org.ehcache.jsr107.EhcacheCachingProvider
config: classpath:ehcache3.xml #配置ehcache的配置文件
自定义的类
package com.tonyjoba.pojo;
import jakarta.persistence.*;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.io.Serializable;
@Entity
@Table(name = "users")
public class Users implements Serializable {
public static final long serialVersionUID = 1213312L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Integer id;//注意这里是Integer,即将第二个坑
@NotBlank(message = "用户名不可为空")
@Column(name = "name")
private String name;
@Min(value = 0,message = "年龄不能为负数")
@NotNull(message = "年龄不可为空")
@Column(name = "age")
private Integer age;
@Column(name = "address")
private String address;
public Users() {
}
public Users(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
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;
}
@Max(value = 150,message = "年龄不能大于150")
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
业务代码 这里的key是用的Integer,继续看ehcache3.xml中的配置,出现了问题。
@Cacheable(value="users", key = "#id")
//@Cacheable:对当前查询的对象做缓存处理
@Override
public Users findUserById(Integer id) {
//return this.usersMapper.selectUsersById(id);
return this.usersRepository.findById(id).get();
}
ehcache3.xml (第二坑,key类型不匹配问题报错Persisted key type …is not the same as the configured key type …),可以很容一发现,改成一致的Integer就可以了,但是,改成了一致之后,重启boot,会发现还报错。这里是因为第一次启动后,在C:/Users/hahah/Desktop/cache目录下已经生成了一部分的缓存文件,导致一六文件中依旧有不匹配的信息,所以,这里把文件删了就可以了。真的HLS!!!!
<config xmlns='http://www.ehcache.org/v3'>
<!-- 持久化 路径 -->
<persistence directory="C:/Users/hahah/Desktop/cache"/>
<!-- 缓存模版,此处为了显示其用法,也可以不用模版直接在cache中配置与模版参数相同 -->
<cache-template name="oneHourTemplate">
<!-- <key-type>java.lang.String</key-type>-->
<!-- <value-type>java.lang.String</value-type>-->
<expiry>
<!-- 单位默认为秒当用秒作单位时,可以不填-->
<ttl unit="hours">1</ttl>
</expiry>
<resources>
<!-- 单位默认为entries当用entries作单位时,可以不填-->
<heap>100</heap>
<offheap unit="MB">5</offheap>
<!-- persistent 默认为false可以不填-->
<disk unit="MB">1024</disk>
</resources>
</cache-template>
<!-- 缓存对象,如果使用了模版会覆盖模版中的内容,使用uses-template=""来引用模版 -->
<cache alias="mycache" uses-template="oneHourTemplate">
</cache>
<cache alias="users">
<!-- 第二坑,注意这里的key是Long,而不是我们指定的key类型Integer,所以需要修改成Integer-->
<key-type>java.lang.Long</key-type>
<value-type>com.tonyjoba.pojo.Users</value-type>
<expiry>
<tti unit="seconds">10</tti>
</expiry>
<resources>
<heap unit="MB">10</heap>
<offheap unit="MB">50</offheap>
<disk persistent="true" unit="MB">500</disk>
</resources>
</cache>
</config>
Caused by: java.lang.IllegalArgumentException: Persisted key type 'java.lang.Integer' is not the same as the configured key type 'java.lang.Long'
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.recoverBackingMap(OffHeapDiskStore.java:184) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.getBackingMap(OffHeapDiskStore.java:159) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore.access$600(OffHeapDiskStore.java:90) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.init(OffHeapDiskStore.java:441) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initStore(OffHeapDiskStore.java:437) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.disk.OffHeapDiskStore$Provider.initAuthoritativeTier(OffHeapDiskStore.java:483) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.impl.internal.store.tiering.TieredStore$Provider.initStore(TieredStore.java:549) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.core.EhcacheManager$7.init(EhcacheManager.java:514) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.core.StatusTransitioner.runInitHooks(StatusTransitioner.java:130) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.core.StatusTransitioner.access$000(StatusTransitioner.java:33) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
at org.ehcache.core.StatusTransitioner$Transition.succeeded(StatusTransitioner.java:189) ~[ehcache-3.10.8-jakarta.jar:3.10.8]
...
Boot启动配置,添加 @EnableCaching
package com.tonyjoba;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@MapperScan("com.tonyjoba.mapper")
@EnableCaching
public class SpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSsmApplication.class, args);
}
}
一切修正了之后,重启,搞掂!!!看到logo真嗨森
D:\WorkSoftInstallSpace\java17\jdk-17.0.12\bin\java.exe -agentlib...
Connected to the target VM, address: '127.0.0.1:60252', transport: 'socket'
_________ ________ ________ ___ ___ ___ ________ ________ ________
|\___ ___\\ __ \|\ ___ \ |\ \ / /| |\ \|\ __ \|\ __ \|\ __ \
\|___ \ \_\ \ \|\ \ \ \\ \ \ \ \ \/ / / \ \ \ \ \|\ \ \ \|\ /\ \ \|\ \
\ \ \ \ \ \\\ \ \ \\ \ \ \ \ / / __ \ \ \ \ \\\ \ \ __ \ \ __ \
\ \ \ \ \ \\\ \ \ \\ \ \ \/ / / |\ \\_\ \ \ \\\ \ \ \|\ \ \ \ \ \
\ \__\ \ \_______\ \__\\ \__\__/ / / \ \________\ \_______\ \_______\ \__\ \__\
\|__| \|_______|\|__| \|__|\___/ / \|________|\|_______|\|_______|\|__|\|__|
\|___|/
2024-11-19T02:47:15.814+08:00 INFO 19216 --- [ main] com.tonyjoba.SpringBootSsmApplication : Starting SpringBootSsmApplication using Java 17.0.12 with PID 19216
2024-11-19T02:47:21.768+08:00 INFO 19216 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-11-19T02:47:21.780+08:00 INFO 19216 --- [ main] com.tonyjoba.SpringBootSsmApplication : Started SpringBootSsmApplication in 6.565 seconds (process running for 7.485)