spring-boot JSR107缓存实战

本文介绍了如何在Spring Boot项目中引入缓存机制,并通过具体示例展示了使用spring-boot-starter-cache依赖来配置Spring Boot缓存的过程。此外还探讨了JSR107和ehcache的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天在开发的项目中,考虑引入一些缓存机制。顺便又了解了一下spring-boot的缓存、以及JSR107、ehcache。并做了一些使用实例。

spring-boot缓存使用实例

spring-boot中引入依赖spring-boot-starter-cache,pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
/**
 * 启动类
 */
@SpringBootApplication
@EnableAutoConfiguration
@EnableCaching // 启用缓存
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

/**
 * restful类
 */
@RestController
public class SampleController {
    @Autowired
    private SampleServiceImpl sampleService;

    @RequestMapping("/sample/test")
    public BaseQueryParam test(BaseQueryParam dto) {
        return sampleService.testCache(dto);
    }

}

@Service
public class SampleServiceImpl {

    // 取第一个参数可以用这几种姿势#root.args[1]或#p0或#a0
    @Cacheable(value="SampleServiceImpl", key="#p0.resourceId")
    public BaseQueryParam testCache(BaseQueryParam param) {
        System.out.println("第1次访问时未缓存,打印此文本");
        return param;
    }

}

public class BaseQueryParam {
    /**
     * 资源标识。主要用来标识需要访问的资源类型
     */
    private String resourceId;

    public String getResourceId() {
        return resourceId;
    }

    public void setResourceId(String resourceId) {
        this.resourceId = resourceId;
    }

}

测试:

http://localhost:8080/sample/test?resourceId=abc

访问的时候当传入的参数resourceId一样时,第1次控制台打印“第1次访问时未缓存,打印此文本”,后面就没有打印。

生命周期:如果没检测到EhCache3,Hazelcast,Infinispan等类型,将会使用Simple类型,即使用ConcurrentHashMap进行缓存,这种类型的缓存是永久有效的。具体的使用可以参考org.springframework.cache.concurrent.ConcurrentMapCacheManager

使用JSR107和ehcache

JSR107的注解为@CacheResult,springboot建议不要和@Cacheable混合使用。同时改为使用ehcache来配置缓存,可以有效的管理内存的占用、缓存的生命周期等。

spring-boot中引入依赖spring-boot-starter-cachepom.xml中增加:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
</dependency>
/**
 * 启动类
 */
@SpringBootApplication
@EnableAutoConfiguration
@EnableCaching // 启用缓存
public class Application extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
}

/**
 * restful类
 */
@RestController
public class SampleController {
    @Autowired
    private SampleServiceImpl sampleService;

    @RequestMapping("/sample/test")
    public BaseQueryParam test(BaseQueryParam dto) {
        return sampleService.testCache(dto);
    }

}

@Service
public class SampleServiceImpl {

    // JSR107的注解为@CacheResult,springboot建议不要和@Cacheable混合使用
    @CacheResult(cacheName = "SampleServiceImpl", cacheKeyGenerator = SampleCacheKeyGenerator.class)
    public BaseQueryParam testCache(BaseQueryParam param) {
        System.out.println("第1次访问时未缓存,打印此文本");
        return param;
    }

    /**
     * 用于生成key的类
     */
    public static class SampleCacheKeyGenerator implements CacheKeyGenerator {

        @Override
        public GeneratedCacheKey generateCacheKey(CacheKeyInvocationContext<? extends Annotation> arg0) {
            BaseQueryParam param = (BaseQueryParam) (arg0.getAllParameters()[0].getValue());
            if (null == param) {
                return null;
            }
            return new SampleGeneratedCacheKey(param.getResourceId());
        }

    }

    /**
     * 缓存key类
     */
    public static class SampleGeneratedCacheKey implements GeneratedCacheKey {
        private static final long serialVersionUID = 1L;
        private final String key;

        public SampleGeneratedCacheKey(String key) {
            this.key = key;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((key == null) ? 0 : key.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            SampleGeneratedCacheKey other = (SampleGeneratedCacheKey) obj;
            if (key == null) {
                if (other.key != null)
                    return false;
            } else if (!key.equals(other.key))
                return false;
            return true;
        }

    }

}

public class BaseQueryParam implements Serializable { // ehcache缓存必须要实现Serializable接口
    /**
     * 资源标识。主要用来标识需要访问的资源类型
     */
    private String resourceId;

    public String getResourceId() {
        return resourceId;
    }

    public void setResourceId(String resourceId) {
        this.resourceId = resourceId;
    }

}

application.properties配置:

>>>>阅读全文

C:\Users\Administrator\.jdks\ms-17.0.15\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-Dmanagement.endpoints.jmx.exposure.include=*" "-javaagent:C:\Users\Administrator\AppData\Local\Programs\IntelliJ IDEA Ultimate 2025.1.3\lib\idea_rt.jar=59531" -Dfile.encoding=UTF-8 -classpath C:\Users\Administrator\Desktop\考题示例\考题示例\demo\target\classes;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-web\3.1.5\spring-boot-starter-web-3.1.5.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter\3.1.5\spring-boot-starter-3.1.5.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot\3.1.5\spring-boot-3.1.5.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-core\6.0.13\spring-core-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-jcl\6.0.13\spring-jcl-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\yaml\snakeyaml\1.33\snakeyaml-1.33.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-json\3.1.5\spring-boot-starter-json-3.1.5.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.15.3\jackson-datatype-jdk8-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.15.3\jackson-datatype-jsr310-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.15.3\jackson-module-parameter-names-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-tomcat\3.1.5\spring-boot-starter-tomcat-3.1.5.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-core\10.1.15\tomcat-embed-core-10.1.15.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-el\10.1.15\tomcat-embed-el-10.1.15.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\tomcat\embed\tomcat-embed-websocket\10.1.15\tomcat-embed-websocket-10.1.15.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-web\6.0.13\spring-web-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-beans\6.0.13\spring-beans-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\io\micrometer\micrometer-observation\1.10.12\micrometer-observation-1.10.12.jar;D:\apache-maven-3.9.10\maven-repository\io\micrometer\micrometer-commons\1.10.12\micrometer-commons-1.10.12.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-webmvc\6.0.13\spring-webmvc-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-aop\6.0.13\spring-aop-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-context\6.0.13\spring-context-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-expression\6.0.13\spring-expression-6.0.13.jar;D:\apache-maven-3.9.10\maven-repository\com\alibaba\druid-spring-boot-starter\1.2.18\druid-spring-boot-starter-1.2.18.jar;D:\apache-maven-3.9.10\maven-repository\com\alibaba\druid\1.2.18\druid-1.2.18.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-autoconfigure\1.5.22.RELEASE\spring-boot-autoconfigure-1.5.22.RELEASE.jar;D:\apache-maven-3.9.10\maven-repository\org\glassfish\jaxb\jaxb-runtime\2.3.2\jaxb-runtime-2.3.2.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\xml\bind\jakarta.xml.bind-api\2.3.2\jakarta.xml.bind-api-2.3.2.jar;D:\apache-maven-3.9.10\maven-repository\org\glassfish\jaxb\txw2\2.3.2\txw2-2.3.2.jar;D:\apache-maven-3.9.10\maven-repository\com\sun\istack\istack-commons-runtime\3.0.8\istack-commons-runtime-3.0.8.jar;D:\apache-maven-3.9.10\maven-repository\org\jvnet\staxex\stax-ex\1.8.1\stax-ex-1.8.1.jar;D:\apache-maven-3.9.10\maven-repository\com\sun\xml\fastinfoset\FastInfoset\1.2.16\FastInfoset-1.2.16.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\activation\jakarta.activation-api\1.2.1\jakarta.activation-api-1.2.1.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\3.0.3\mybatis-spring-boot-starter-3.0.3.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\boot\spring-boot-starter-jdbc\3.2.0\spring-boot-starter-jdbc-3.2.0.jar;D:\apache-maven-3.9.10\maven-repository\com\zaxxer\HikariCP\5.0.1\HikariCP-5.0.1.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-jdbc\6.1.1\spring-jdbc-6.1.1.jar;D:\apache-maven-3.9.10\maven-repository\org\springframework\spring-tx\6.1.1\spring-tx-6.1.1.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\3.0.3\mybatis-spring-boot-autoconfigure-3.0.3.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\mybatis\3.5.14\mybatis-3.5.14.jar;D:\apache-maven-3.9.10\maven-repository\org\mybatis\mybatis-spring\3.0.3\mybatis-spring-3.0.3.jar;D:\apache-maven-3.9.10\maven-repository\org\projectlombok\lombok\1.18.30\lombok-1.18.30.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\enterprise\jakarta.enterprise.cdi-api\3.0.0\jakarta.enterprise.cdi-api-3.0.0.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\el\jakarta.el-api\4.0.0\jakarta.el-api-4.0.0.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\interceptor\jakarta.interceptor-api\2.0.0\jakarta.interceptor-api-2.0.0.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\inject\jakarta.inject-api\2.0.0\jakarta.inject-api-2.0.0.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\ws\rs\jakarta.ws.rs-api\3.0.0\jakarta.ws.rs-api-3.0.0.jar;D:\apache-maven-3.9.10\maven-repository\jakarta\servlet\jakarta.servlet-api\5.0.0\jakarta.servlet-api-5.0.0.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-databind\2.15.3\jackson-databind-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-annotations\2.15.3\jackson-annotations-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\com\fasterxml\jackson\core\jackson-core\2.15.3\jackson-core-2.15.3.jar;D:\apache-maven-3.9.10\maven-repository\org\slf4j\slf4j-api\2.0.12\slf4j-api-2.0.12.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\logging\log4j\log4j-slf4j2-impl\2.23.1\log4j-slf4j2-impl-2.23.1.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\logging\log4j\log4j-api\2.23.1\log4j-api-2.23.1.jar;D:\apache-maven-3.9.10\maven-repository\org\apache\logging\log4j\log4j-core\2.23.1\log4j-core-2.23.1.jar com.example.fundprofit.FundProfitApplication . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v3.1.5) 2025-07-12T10:34:20.673+08:00 INFO 5860 --- [ main] c.e.f.FundProfitApplication : Starting FundProfitApplication using Java 17.0.15 with PID 5860 (C:\Users\Administrator\Desktop\考题示例\考题示例\demo\target\classes started by Administrator in C:\Users\Administrator\Desktop\考题示例\考题示例\demo) 2025-07-12T10:34:20.680+08:00 INFO 5860 --- [ main] c.e.f.FundProfitApplication : No active profile set, falling back to 1 default profile: "default" 2025-07-12T10:34:20.845+08:00 WARN 5860 --- [ main] o.s.b.d.FailureAnalyzers : FailureAnalyzers [org.springframework.boot.autoconfigure.diagnostics.analyzer.NoSuchBeanDefinitionFailureAnalyzer] implement BeanFactoryAware or EnvironmentAware. Support for these interfaces on FailureAnalyzers is deprecated, and will be removed in a future release. Instead provide a constructor that accepts BeanFactory or Environment parameters. 2025-07-12T10:34:20.847+08:00 ERROR 5860 --- [ main] o.s.b.SpringApplication : Application run failed java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getExcludeAutoConfigurationsProperty(AutoConfigurationImportSelector.java:205) ~[spring-boot-autoconfigure-1.5.22.RELEASE.jar:1.5.22.RELEASE] at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getExclusions(AutoConfigurationImportSelector.java:199) ~[spring-boot-autoconfigure-1.5.22.RELEASE.jar:1.5.22.RELEASE] at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports(AutoConfigurationImportSelector.java:96) ~[spring-boot-autoconfigure-1.5.22.RELEASE.jar:1.5.22.RELEASE] at org.springframework.context.annotation.ConfigurationClassParser$DefaultDeferredImportSelectorGroup.process(ConfigurationClassParser.java:821) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:796) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:726) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassParser$DeferredImportSelectorHandler.process(ConfigurationClassParser.java:697) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:182) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:415) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:287) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:344) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:115) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:779) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:597) ~[spring-context-6.0.13.jar:6.0.13] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.5.jar:3.1.5] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:738) [spring-boot-3.1.5.jar:3.1.5] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:440) [spring-boot-3.1.5.jar:3.1.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-3.1.5.jar:3.1.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) [spring-boot-3.1.5.jar:3.1.5] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) [spring-boot-3.1.5.jar:3.1.5] at com.example.fundprofit.FundProfitApplication.main(FundProfitApplication.java:11) [classes/:?] Caused by: java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?] at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[?:?] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525) ~[?:?] ... 21 more 进程已结束,退出代码为 1 请解释下原因给出方法
最新发布
07-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值