繁体   English   中英

什么是适合Java Map的Spring Cache配置及其值?

[英]What is a right Spring Cache Configuration for Java Map and its values?

我有下一个服务,它返回整个地图和一个键的值。

@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注释来做到这一点? 目前,它为这两种方法分别设置了缓存条目。

当您方法分成不同的服务(公共外观)时,它可以正常工作。

spring-caching示例/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)

;)

你能做点什么吗?

public String getMessage(String key) {
    return findMessages().get(key)
}

我认为您不需要使用@Cacheable来注释getMessage,因为您正在访问已经缓存的findMessages()。

啊@ xerx593打赌我:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM