Spring 3.1缓存抽象教程

即将发布的Spring 3.1版本中引入的新功能之一是缓存抽象之一

Spring Framework提供了对将缓存透明添加到现有Spring应用程序中的支持。 事务支持类似,缓存抽象允许一致使用各种缓存解决方案,而对代码的影响最小。

从本质上讲,抽象将缓存应用于Java方法,从而基于缓存中可用的信息减少了执行次数。 也就是说,每次调用目标方法时,抽象将应用缓存行为,以检查该方法是否已针对给定参数执行。 如果有,则返回缓存的结果,而不必执行实际的方法; 如果还没有,则执行该方法,将结果缓存并返回给用户,以便下次调用该方法时,返回缓存的结果。

这个概念当然不是什么新鲜事物。 您可以查看Spring,AspectJ,Ehcache方法的缓存Aspect是我们JCG合作伙伴之一Brian Du Preez撰写的一篇非常有趣的文章,其中使用了Aspect Oriented Programming

顾名思义,“缓存抽象”不是实际的实现,因此它需要使用实际的存储来存储缓存数据。 您可能已经猜到了,开箱即用地提供了Ehcache支持。 还有一个基于JDK的ConcurrentMap的实现,您实际上可以插入不同的后端缓存

现在,让我们看一些有关缓存抽象的示例代码。 为此,我将使用JCG的另一位合作伙伴 James Carr 在Spring 3.1.0.M1中提供的非常有用的Cache Abstraction 。 确保在此过程中将Spring Cache包Javadocs标记为书签。

(注意:对原始帖子进行了少量编辑以提高可读性)

昨天发布的另一个新功能与我同时尝试了一些基于注释的缓存策略。 缓存抽象基本上是从现有项目中获取约定,并使其成为Spring核心的一部分。

本质上,它引入了一个新接口CacheManager ,可以通过特定的缓存实现来实现。 从那里开始,它添加了一些新的注释以使方法可缓存。 这是一个使用我以前的posts对象的示例。

package com.jamescarr.example;

import java.util.Collection;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;

@Repository
public class MemoryMessageRepository implements MessageRepository {

    private static final Logger LOG =
           LoggerFactory.getLogger(MemoryMessageRepository.class);

    private final Map<String, Message> messages = 
           new ConcurrentHashMap<String, Message>();

    @Cacheable("message")
    public Message getMessage(String title){
        LOG.info("Fetching message");
        return messages.get(title);
    }
    @CacheEvict(value="message", key="message.title")
    public void save(Message message){
        LOG.info("Saving message");
        messages.put(message.getTitle(), message);
    }
    public Collection<Message> findAll() {
        return messages.values();
    }
    
    @PostConstruct
    public void addSomeDefaultMessages(){
        save(new Message("Hello", "Hello World"));
        save(new Message("Appointment", "Remember the milk!"));
    }
    
}

在这里,您会发现finder方法具有@Cachable批注,其名称指定了要存储到的缓存。 它还可以使用其他属性,例如,使用表达式语言从传入的参数确定键的键。默认值为所有方法参数的值。 在保存方法上,我使用@CacheEvict从缓存中删除已缓存的元素(如果已存在)。

当然,这本身并不会起作用,因此您必须自己启用它(这很好……您需要做的最后一件事是发现一个生产应用程序,将不需要缓存的内容缓存起来)。 不幸的是,在撰写本文时,我还没有发现如何在非xml中执行此操作,因此这是启用它并使用ehcache作为实现的spring xml文件。

<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:cache="http://www.springframework.org/schema/cache"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
  <cache:annotation-driven />
  
        <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcache"/>
        <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
                p:config-location="classpath:com/jamescarr/example/ehcache.xml"/>
 </beans>

ehcache配置:

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <cache name="message"
       maxElementsInMemory="100"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"/>
    
</ehcache>

最后将其添加到AppConfiguration中,其中包括执行一个简单的@ImportResource

package com.jamescarr.configuration;
import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

import com.jamescarr.example.MessagePrinter;

@Configuration
@ComponentScan("com.jamescarr.example")
@ImportResource("classpath:com/jamescarr/example/cache-context.xml")
public class AppConfig {
        @Autowired
        private MessagePrinter messagePrinter;
        @PostConstruct
        public void doSomething(){
                messagePrinter.printMessage("Hello");
                messagePrinter.printMessage("Hello");
                
        }
        public static void main(String[] args) {
                new AnnotationConfigApplicationContext(AppConfig.class);
        }
}

在运行此示例时,第一次单击该方法时应该有一条日志消息,然后第二次则看不到(因为它是从缓存中拉出的。对于为可能只是为了实现方法的方法实现备忘录化而言 ,这绝对是很棒的选择进行一些CPU密集型计算(但是在一组输入的情况下给出了确切的预期结果)。我为在该领域进行更多工作而感到兴奋……我之前已经做过方法级缓存(这很常见),但是无需DIY就可以使用它。

就是这样。 一个简单的指南,可帮助您开始使用James Carr的 Spring的Cache抽象 。 别忘了分享!

相关文章:


翻译自: https://www.javacodegeeks.com/2011/02/spring-31-cache-abstraction-tutorial.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值