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倍)。

相关文章
|
25天前
|
缓存 安全 Android开发
Android经典实战之用Kotlin泛型实现键值对缓存
本文介绍了Kotlin中泛型的基础知识与实际应用。泛型能提升代码的重用性、类型安全及可读性。文中详细解释了泛型的基本语法、泛型函数、泛型约束以及协变和逆变的概念,并通过一个数据缓存系统的实例展示了泛型的强大功能。
27 2
|
1月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
7天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
1月前
|
NoSQL Java Redis
Redis6入门到实战------ 八、Redis与Spring Boot整合
这篇文章详细介绍了如何在Spring Boot项目中整合Redis,包括在`pom.xml`中添加依赖、配置`application.properties`文件、创建配置类以及编写测试类来验证Redis的连接和基本操作。
Redis6入门到实战------ 八、Redis与Spring Boot整合
|
23天前
|
Java API UED
【实战秘籍】Spring Boot开发者的福音:掌握网络防抖动,告别无效请求,提升用户体验!
【8月更文挑战第29天】网络防抖动技术能有效处理频繁触发的事件或请求,避免资源浪费,提升系统响应速度与用户体验。本文介绍如何在Spring Boot中实现防抖动,并提供代码示例。通过使用ScheduledExecutorService,可轻松实现延迟执行功能,确保仅在用户停止输入后才触发操作,大幅减少服务器负载。此外,还可利用`@Async`注解简化异步处理逻辑。防抖动是优化应用性能的关键策略,有助于打造高效稳定的软件系统。
31 2
|
25天前
|
缓存 NoSQL 数据库
go-zero微服务实战系列(五、缓存代码怎么写)
go-zero微服务实战系列(五、缓存代码怎么写)
|
20天前
|
缓存 Java Spring
Spring缓存实践指南:从入门到精通的全方位攻略!
【8月更文挑战第31天】在现代Web应用开发中,性能优化至关重要。Spring框架提供的缓存机制可以帮助开发者轻松实现数据缓存,提升应用响应速度并减少服务器负载。通过简单的配置和注解,如`@Cacheable`、`@CachePut`和`@CacheEvict`,可以将缓存功能无缝集成到Spring应用中。例如,在配置文件中启用缓存支持并通过`@Cacheable`注解标记方法即可实现缓存。此外,合理设计缓存策略也很重要,需考虑数据变动频率及缓存大小等因素。总之,Spring缓存机制为提升应用性能提供了一种简便快捷的方式。
27 0
|
23天前
|
JSON Java API
解码Spring Boot与JSON的完美融合:提升你的Web开发效率,实战技巧大公开!
【8月更文挑战第29天】Spring Boot作为Java开发的轻量级框架,通过`jackson`库提供了强大的JSON处理功能,简化了Web服务和数据交互的实现。本文通过代码示例介绍如何在Spring Boot中进行JSON序列化和反序列化操作,并展示了处理复杂JSON数据及创建RESTful API的方法,帮助开发者提高效率和应用性能。
52 0
|
23天前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
54 0
|
23天前
|
缓存 NoSQL Java
惊!Spring Boot遇上Redis,竟开启了一场缓存实战的革命!
【8月更文挑战第29天】在互联网时代,数据的高速读写至关重要。Spring Boot凭借简洁高效的特点广受开发者喜爱,而Redis作为高性能内存数据库,在缓存和消息队列领域表现出色。本文通过电商平台商品推荐系统的实战案例,详细介绍如何在Spring Boot项目中整合Redis,提升系统响应速度和用户体验。
44 0