java - 什么是 Java 映射的正确 Spring 缓存配置及其值?

标签 java spring caching spring-boot

我有下一个服务,它通过一个键返回整个 map 和一个值。

@Service
@CacheConfig(cacheNames = "messages")
public class MessageService {

    private final MessageRepository messageRepository;

    @Autowired
    public MessageService(MessageRepository messageRepository) {
        this.messageRepository = messageRepository;
    }

    @Cacheable
    public Map<String, String> findMessages() {
        return messageRepository.findAll();
    }

    @Cacheable(key = "#key")
    public String getMessage(String key) {
        return messageRepository.findByKey(key);
    }
}

当调用 findMessages() 方法时,我想将所有消息保存在缓存中。当 getMessage(String key) 被调用时,它应该从缓存中返回一个值,而不是从存储库中返回一个值。是否可以使用 Spring 注释来做到这一点?目前,这两种方法都有单独的缓存条目。

最佳答案

当您将方法分离到不同的服务(公共(public)外观)时,它会按预期工作。

spring-caching example开始(/complete),我将 SimpleBookRepository 移动到一个新类(应该是“缓存服务”)并进行了一些小的调整:

@Component
public class SimpleCache {

    @Cacheable("map")
    public Map<String, String> getMap() {
        simulateSlowService();
        Map<String, String> result = new HashMap<>();
        result.put("foo", "bar");
        result.put("bar", "foo");
        return result;
    }

    // Don't do this at home
    private void simulateSlowService() {
        try {
            long time = 3000L;
            Thread.sleep(time);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
    }

}

一些小的调整以匹配问题/示例:

package hello;

public interface BookRepository {
    //originally it returned {@link hello.Book}
    String getByIsbn(String isbn);
}

...并引入(作为缓存门面/调用者...在缓存 getByIsbn() 中没有任何意义!!):

@Component
public class SimpleBookRepository implements BookRepository {
    @Autowired
    private transient SimpleCache cache;

    @Override
    public String getByIsbn(String isbn) {
       return cache.getMap().get(isbn);
    }

}

稍微调整一下 AppRunner:

//...
logger.info(".... Fetching books");
logger.info("foo --> {}", bookRepository.getByIsbn("foo"));
logger.info("bar --> {}", bookRepository.getByIsbn("bar"));
logger.info("foo --> {}", bookRepository.getByIsbn("foo"));
logger.info("bar --> {}", bookRepository.getByIsbn("bar"));
logger.info("foo --> {}", bookRepository.getByIsbn("foo"));
logger.info("foo --> {}", bookRepository.getByIsbn("foo"));
//...

...我们得到以下输出:

2017-06-30 15:54:52.584 INFO 3984 --- [ main] hello.AppRunner : .... Fetching books
2017-06-30 15:54:55.616 INFO 3984 --- [ main] hello.AppRunner : foo --> bar
2017-06-30 15:54:55.618 INFO 3984 --- [ main] hello.AppRunner : bar --> foo
2017-06-30 15:54:55.619 INFO 3984 --- [ main] hello.AppRunner : foo --> bar
2017-06-30 15:54:55.619 INFO 3984 --- [ main] hello.AppRunner : bar --> foo
2017-06-30 15:54:55.619 INFO 3984 --- [ main] hello.AppRunner : foo --> bar
2017-06-30 15:54:55.619 INFO 3984 --- [ main] hello.AppRunner : foo --> bar
2017-06-30 15:54:55.623 INFO 3984 --- [ main] hello.Application  : Started Application in 4.982 seconds (JVM running for 5.513)

;)

关于java - 什么是 Java 映射的正确 Spring 缓存配置及其值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44845359/

相关文章:

java - 使用流处理异常

java - 使用 java.lang.management 测量 Java 控制台应用程序使用的内存和 CPU

java - 有没有办法使用 java 套接字程序查找打印机状态?

java - 无法初始化类 org.springframework.osgi.service.importer.support.OsgiServiceProxyFactoryBean

java - Spring FrameworkServlet 在 Tomcat 启动期间不会加载属性

java - SpringMVC + Spring Security Hibernate + Thymeleaf - 我的 pom.xml 太多了吗?

ruby-on-rails - Rails 4 在 Rails.cache.fetch 中跳过缓存

java - 对 Java 事件循环库的建议

java - 咖啡因缓存: write() never get called

c - 如何使用 C 测量 L1、L2 和 L3 缓存延迟?