16

データベース クエリを改善するために spring-cache を使用しています。これは次のように正常に動作します。

@Bean
public CacheManager cacheManager() {
    return new ConcurrentMapCacheManager("books");
}

@Cacheable("books")
public Book getByIsbn(String isbn) {
    return dao.findByIsbn(isbn);
}

しかし今、起動時に完全なブックキャッシュを事前に設定したいと考えています。つまりdao.findAll()、すべての値を呼び出してキャッシュに入れたいということです。このルーチンは、定期的にのみスケジュールする必要があります。

しかし、使用時にキャッシュを明示的に設定するにはどうすればよい@Cacheableですか?

4

7 に答える 7

24

以前と同じようにキャッシュを使用し、スケジューラを追加してキャッシュを更新します。コード スニペットは以下のとおりです。

@Service
public class CacheScheduler {
    @Autowired
    BookDao bookDao;
    @Autowired
    CacheManager cacheManager;

    @PostConstruct
    public void init() {
        update();
        scheduleUpdateAsync();
    }

    public void update() {
        for (Book book : bookDao.findAll()) {
            cacheManager.getCache("books").put(book.getIsbn(), book);
        }
    }
}

KeyGeneratorが 1 つのパラメータのオブジェクトを返すことを確認してください(デフォルト)。または、putToCacheメソッドを公開して、 BookServicecacheManager を直接使用しないようにします。

@CachePut(value = "books", key = "#book.isbn")
public Book putToCache(Book book) {
    return book;
}
于 2015-02-04T00:10:10.280 に答える
1

Olivier が指定したように、Spring は関数の出力を単一のオブジェクトとしてキャッシュするため、findAll で @cacheable 表記を使用しても、後で個別にアクセスできるようにすべてのオブジェクトをキャッシュにロードすることはできません。

キャッシュ内のすべてのオブジェクトをロードできる 1 つの考えられる方法は、使用されているキャッシュ ソリューションによって、起動時にすべてのオブジェクトをロードする方法が提供される場合です。たとえば、NCache / TayzGridなどのソリューションはキャッシュ スタートアップ ローダー機能を提供します。これにより、構成可能なキャッシュ スタートアップ ローダーを使用して、起動時にオブジェクトをキャッシュにロードできます。

于 2015-01-25T19:07:34.460 に答える
-1

別の Bean BookCacheInitialzer を追加します

BookCacheInitialzer で現在の Bean BookService をオートワイヤする

BookCacheInitialzer 擬似コードの PostConstruct メソッド内

次に、次のようなことができます

class BookService {
    @Cacheable("books")
    public Book getByIsbn(String isbn) {
        return dao.findByIsbn(isbn);
    }
    
    public List<Book> books;

    @Cacheable("books")
    public Book getByIsbnFromExistngBooks(String isbn) {
        return searchBook(isbn, books);
    }
}

class BookCacheInitialzer {

    @Autowired
    BookService  service;

    @PostConstruct
    public void initialize() {
        books = dao.findAll();
        service.books = books;
        for(Book book:books) {
            service.getByIsbnFromExistngBooks(book.getIsbn());
        }
    }
}
于 2015-01-14T10:42:31.280 に答える