spring-boot JSR107缓存实战

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

这几天在开发的项目中,考虑引入一些缓存机制。顺便又了解了一下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配置:

# SampleServiceImpl 对应cacheName = "SampleServiceImpl"
spring.cache.cache-names=SampleServiceImpl
spring.cache.ehcache.config=calsspath:ehcache.xml

关于JSR107

https://jcp.org/en/jsr/detail?id=107

描述(网上抄来的):JCache规范定义了一种对Java对象临时在内存中进行缓存的方法,包括对象的创建、共享访问、假脱机(spooling)、失效、各JVM的一致性等,可被用于缓存JSP内最经常读取的数据,如产品目录和价格列表。利用JCACHE,多数查询的反应时间会因为有缓存的数据而加快(内部测试表明反应时间大约快15倍)。

相关文章
|
18天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
42 3
|
18天前
|
安全 Java 开发者
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
23 1
|
18天前
|
安全 Java 测试技术
Spring Boot集成支付宝支付:概念与实战
【4月更文挑战第29天】在电子商务和在线业务应用中,集成有效且安全的支付解决方案是至关重要的。支付宝作为中国领先的支付服务提供商,其支付功能的集成可以显著提升用户体验。本篇博客将详细介绍如何在Spring Boot应用中集成支付宝支付功能,并提供一个实战示例。
53 2
|
9天前
|
缓存 NoSQL Java
Spring Cache之本地缓存注解@Cacheable,@CachePut,@CacheEvict使用
SpringCache不支持灵活的缓存时间和集群,适合数据量小的单机服务或对一致性要求不高的场景。`@EnableCaching`启用缓存。`@Cacheable`用于缓存方法返回值,`value`指定缓存名称,`key`定义缓存键,可按SpEL编写,`unless`决定是否不缓存空值。当在类上使用时,类内所有方法都支持缓存。`@CachePut`每次执行方法后都会更新缓存,而`@CacheEvict`用于清除缓存,支持按键清除或全部清除。Spring Cache结合Redis可支持集群环境。
54 5
|
18天前
|
开发框架 监控 Java
深入探索Spring Boot的监控、管理和测试功能及实战应用
【5月更文挑战第14天】Spring Boot是一个快速开发框架,提供了一系列的功能模块,包括监控、管理和测试等。本文将深入探讨Spring Boot中监控、管理和测试功能的原理与应用,并提供实际应用场景的示例。
21 2
|
18天前
|
Java Spring 容器
深入理解Spring Boot启动流程及其实战应用
【5月更文挑战第9天】本文详细解析了Spring Boot启动流程的概念和关键步骤,并结合实战示例,展示了如何在实际开发中运用这些知识。
27 2
|
18天前
|
JavaScript Java 开发者
Spring Boot中的@Lazy注解:概念及实战应用
【4月更文挑战第7天】在Spring Framework中,@Lazy注解是一个非常有用的特性,它允许开发者控制Spring容器的bean初始化时机。本文将详细介绍@Lazy注解的概念,并通过一个实际的例子展示如何在Spring Boot应用中使用它。
27 2
|
18天前
|
XML 存储 缓存
Spring缓存是如何实现的?如何扩展使其支持过期删除功能?
总之,Spring的缓存抽象提供了一种方便的方式来实现缓存功能,并且可以与各种缓存提供商集成以支持不同的过期策略。您可以根据项目的具体需求选择适合的方式来配置和扩展Spring缓存功能。
21 0
|
18天前
|
XML Java API
Spring Boot 整合 LiteFlow 规则引擎:概念与实战
【4月更文挑战第30天】在现代软件开发中,规则引擎允许我们以声明式的方式定义业务逻辑和决策路径。LiteFlow 是一个轻量级、易于使用的组件式规则引擎,它可以与 Spring Boot 应用无缝整合。本文将介绍如何在 Spring Boot 项目中引入 LiteFlow,实现灵活的业务流程管理。
51 0
|
18天前
|
存储 缓存 Java
【Spring系列笔记】依赖注入,循环依赖以及三级缓存
依赖注入: 是指通过外部配置,将依赖关系注入到对象中。依赖注入有四种主要方式:构造器注入、setter方法注入、接口注入以及注解注入。其中注解注入在开发中最为常见,因为其使用便捷以及可维护性强;构造器注入为官方推荐,可注入不可变对象以及解决循环依赖问题。本文基于依赖注入方式引出循环依赖以及三层缓存的底层原理,以及代码的实现方式。
28 0