1. 캐시 캐시 란 무엇입니까?
캐시라는 단어는 처음으로 CPU 디자인에서 나왔습니다
CPU가 데이터를 읽고 싶을 때, 먼저 CPU 캐시에서 찾아서 즉시 읽고 CPU로 보내서 처리 된 경우 처리합니다. 발견되지 않으면 비교적 느린 메모리에서 읽히고 처리를 위해 CPU로 전송됩니다. 동시에이 데이터가 위치한 데이터 블록이 캐시로 호출되므로 메모리를 호출하지 않고도 전체 데이터 블록을 캐시에서 읽을 수 있습니다. CPU 읽기 캐시 적중률을 매우 높게 만드는 것은이 읽기 메커니즘입니다 (대부분의 CPU는 약 90%에 도달 할 수 있습니다). 이는 다음에 읽은 데이터의 90%가 CPU 캐시에 있으며 메모리에서 약 10% 만 읽어야 함을 의미합니다. 이로 인해 CPU 시간을 크게 절약 할 수 있으며 메모리를 직접 읽을 수 있으며 CPU가 대기하지 않고 데이터를 읽을 수 없습니다. 일반적으로 CPU가 데이터를 읽는 순서는 먼저 캐시 된 다음 메모리입니다.
나중에 먼저 하드 디스크 캐시로 갔다가 애플리케이션 캐시, 브라우저 캐시, 웹 캐시 등으로 갔다!
캐시는 왕입니다! !
스프링 캐시
Spring Cache는 Spring Applications에서 제공하는 완전한 애플리케이션 캐싱 솔루션 세트입니다.
스프링 캐시 자체는 캐시 구현을 제공하지 않지만 통합 인터페이스 및 코드 사양, 구성, 주석 등을 사용하여 캐시의 세부 사항에 너무 많은주의를 기울이지 않고 스프링 애플리케이션에서 다양한 캐시를 사용할 수 있습니다. 스프링 캐시를 사용하면 쉽게 사용할 수 있습니다
ConcurrentMap, Ehcache 2.X, JCache, Redis 등을 포함한 다양한 캐시 구현
스프링의 캐시 정의
인터페이스 org.springframework.cache.cache를 포함하여 스프링의 캐시 정의.
주로 다음 방법을 제공합니다
// 지정된 키 <t> t get (Object Key, Class <T> type)에 따라 값을 가져옵니다. // 해당 키 무효 풋 (개체 키, 개체 값)에 따라 지정된 값을 캐시에 저장; // 지정된 값 void Evict (개체 키)에 따라 캐시에 저장하십시오.
캐시가 실제로 키 가치 구조라는 정의에서보기는 어렵지 않습니다. 지정된 키를 통해 해당 값을 작동합니다.
캐시 관리자
캐시는 키 값의 모음이지만, 우리 프로젝트에는 사용자 캐시, 부서 캐시 등과 같은 다양한 비즈니스 주제의 다양한 캐시가있을 수 있습니다. 이러한 캐시는 논리적으로 분리되어 있습니다. 이러한 캐시를 구별하기 위해 다양한 캐시를 관리하기 위해 org.springframework.cache.cachemanager가 제공됩니다. 이 인터페이스에는 두 가지 방법 만 포함되어 있습니다
// 이름 캐시 getCache (문자열 이름)에 따라 해당 주제의 캐시를 가져옵니다. // 모든 주제의 캐시를 가져옵니다. <string> getCachenames ();
이 인터페이스에서는 캐시에서 추가 및 삭제 작업을 수행 할 수 없습니다. 이러한 작업은 다양한 Cachemanager 구현에 의해 내부적으로 완료되어야하며 공개해서는 안됩니다.
주석 기반 캐시
이론적으로 데이터의 캐시 작동은 비즈니스 자체와 그다지 관련이 없습니다. 캐시의 읽기 및 쓰기 작업을 기본 코드 로직과 분리해야합니다. 스프링이 분리되는 방식은 주석을 기준으로합니다 (물론 JSR-107 등 등은 주석을 기반으로합니다).
Spring은 @cachable, @cacheput, @cacheevict 및 기타 주석을 포함한 일련의 주석을 제공하여 캐시 작동을 단순화합니다. 이 주석은 org.springframework.cache.annotation 패키지에 있습니다.
2. 예
스프링 캐시를 사용하여 스프링 부팅을 사용하는 간단한 예
스프링 부트 캐시를 기반으로 한 단계별로 예제를 작성하겠습니다.
새 Spring Boot 프로젝트를 작성하고 다음 종속성을 소개하십시오.
<pectionies> <pectionency> <groupId> org.springframework.boot </groupId> <artifactid> Spring-Boot-Starter-Cache </artifactid> </depectency> <groupId> org.springframework.boot </groupid> <ArpenifactId> spring-boot-starter-web> </artifactid> <groupid> org.springframework.boot </groupid> <artifactid> 스프링-부트 스타터-테스트 </artifactid> <scope> test </scope> </fectionency> </fectionencies>
그 중 스프링 부트 스타터 캐시는 캐시의 주요 종속성입니다.
응용 프로그램 클래스를 수정하고 @enablecaching을 활성화하는 주석을 추가하십시오.
@SpringBootApplication@enableCachingPublic Class Cachesimplepplication {public static void main (string [] args) {springApplication.run (cachesimplepplication.class, args); }}@enablecache 주석은 Spring의 캐싱 메커니즘을 시작하여 응용 프로그램이 모든 캐시 관련 주석을 감지하고 작동을 시작할 수 있습니다. 또한 응용 프로그램에서 주입하여 사용할 수있는 CacheManager Bean을 만듭니다.
새로운 RestController 클래스를 만듭니다
@restcontroller @requestmapping ( "/") 공개 클래스 캐시 콘 트롤러 {@autowired private cachetestservice cachetestservice; / ** * id * * @param id * @return */ @getMapping ( "{id}") public String test (@pathvariable ( "id") String id) {return cachetestservice.get (id); } / ** * id * * @param id * @return * / @deletemapping ( "{id}") public string delete (@pathvarible ( "id") 문자열 id) {return cachetestservice.delete (id); } / ** * id * * @param id * @return * / @postmapping public string save (@requestparam ( "id") 문자열 id, @requestparam ( "value") 문자열 값) {return cachetestservice.save (id, value); } / ** * 새 ID에 대한 정보 * * @param id * @return * / @putMapping ( "{id}") public String update (@PathVariable ( "id") String id, @requestParam ( "value") 문자열 값) {return cachetestService.update (id, value); }}이 클래스는 서비스를 호출하여 추가, 삭제, 수정 및 확인의 실제 작업을 구현하기 위해 서비스를 호출합니다.
서비스 구현
다음으로 서비스를 구현하고자합니다
@ServicePublic Class SimpleCacheCetestServiceImpl 구현 CachetestService {private static final logger = loggerfactory.getLogger (simplecCacheStestServiceImpl.class); 개인 최종지도 <문자열, 문자열> 엔티티 = New Hashmap <> (); public simpleceCeTestServiceImpl () {entities.put ( "1", "this no 1"); } @autowired Private Cachemanager CacheManager; @override @cachable (cachenames = "test") public String get (string id) {// 데이터 생성 시간을 기록하고, 긴 시간을 테스트하고 비교하는 데 사용됩니다 = new date (). gettime (); // 중고 Cachemanager logger.info ( "캐시 메너는" + cachemanager)를 인쇄합니다. // 로그 logger.info ( "get value by id =" + id + ", 시간은" + time); "id get value get value id id =" + id + ", 값은" + entities.get (id); } @override public string delete (String id) {return entities.remove (id); } @override public String save (문자열 id, 문자열 값) {logger.info ( " + id +" + value + "; Entities.put (id, value); 반환 값; } @override public string update (문자열 ID, 문자열 값) {return entities.put (id, value); }}은닉처
먼저 Get 메소드에 @Cachable 주석을 추가하고 코드 테스트를 실행하십시오.
우리는 테스트에 Postman을 사용하고 테스트 주소는 http : // localhost : 8080/1, 브라우저는 id = 1, 값 isthis no 1, 서버 콘솔은 두 줄의 로그 라인을 인쇄합니다.
ID = 1으로 값을 얻습니다. 값은 ID = 1, 시간은 1516004770216입니다.
그러나 브라우저 주소를 다시 새로 고치면 브라우저가 정상적으로 반환되지만 콘솔은 더 이상 인쇄되지 않습니다. 그 이유는 우리가 두 번째로 부르면 스프링이 더 이상 메소드를 실행하지 않고 캐시 된 값을 직접 가져 오기 때문입니다. 스프링 캐시는 테스트 명명 된 캐시의 키로 함수의 반환 값을 캐시합니다.
여기서 @Cachable 주석을 사용하고 주석의 캐시 이름은 여기에서 읽는 캐시를 지정합니다. 여기서는 키가 Cachename = "Test"의 ID 인 캐시 객체를 검색합니다.
캐시 된 데이터를 삭제합니다
위의 프로그램에서 삭제 요청을 통해 지정된 값을 삭제하고 http : // localhost : 8080/1로 삭제 요청을 보내면 값이지도에서 삭제되었지만 http : // localhost : 8080/1에 대한 요청을 얻을 때 여전히 값을 얻을 수 있습니다. 데이터를 삭제할 때 캐시에서 데이터를 삭제하지 않았기 때문입니다. 이전 GET 메소드에서는 메소드의 작동 결과가 여전히 저장됩니다. 스프링은 그것을 다시 읽지 않지만 캐시를 직접 읽습니다. 현재, 우리는 방법 전에 주석을 추가합니다
@override@cacheevict (cachenames = "test") public String delete (String id) {return entities.remove (id);}테스트 후 먼저 GET 요청을 호출하면 반환 값이 get 값으로 ID = 1으로 올바르게 표시됩니다. 값은 1입니다.
그런 다음 삭제 요청을 호출합니다. 캐시 및 맵에서 데이터를 삭제하고 GET 요청을 다시 호출하십시오. 이 시점에서 id = 1에 의한 get 값, 값은 null이므로 값이 실제로 캐시에서 삭제되었음을 의미합니다.
여기서 우리는 @cacheevict 주석을 사용합니다. 캐시 이름은 삭제할 캐시 데이터를 지정합니다. 기본적으로 메소드 매개 변수는 삭제 된 키로 사용됩니다.
캐시 업데이트
프로그램 이이 시점에 도달하면 게시물 요청을 실행하면 요청 본문은 id = 1 & value = new1입니다. 현재 콘솔 인쇄는 Key 1을 사용하여 값 New Value1을 절약하고 코드는 값을 맵에 저장하지만 GET 요청을 실행할 때 리턴 값이 이전 상태에 있음을 알게됩니다. 이것이 우리가 사용할 수있는 것입니다
@override@cacheput (cachenames = "test", key = "#id") public string save (문자열 id, 문자열 값) {logger.info ( " + value +"key " + id); return entities.put (id, value);}코드를 다시 고정 시키면 먼저 맵과 캐시에서 데이터를 삭제하기 위해 삭제 요청을 보냅니다. 그런 다음 게시물 요청을 보내고 데이터를지도에 씁니다. 마지막으로 GET 요청을 보내면 값을 지금 올바르게 검색 할 수 있고 콘솔은 맵에서 얻은 데이터의 로그를 인쇄하지 않습니다.
@Cacheput 주석이 여기에 사용됩니다. 이 주석의 기능은 메소드의 리턴 값을 주어진 키에 따라 캐시 이름으로 지정된 캐시에 작성하는 것입니다.
마찬가지로, 수정이 캐시 된 데이터를 새로 고칠 수 있도록 PUT 방법에 @CachePut 주석을 추가해야합니다.
이 시점에서 첨가, 삭제, 수정 및 쿼리를 포함한 간단한 캐시 애플리케이션이 완료됩니다.
3. 키 포인트
몇 가지 메모
알아채다
@Cachable과 @CachePut은 지정된 키에 따라 메소드의 실행 결과를 캐시에 넣습니다. @Cachable이 실행되면 먼저 캐시에 데이터가 있는지 여부를 먼저 감지합니다. 그렇다면 캐시에서 직접 읽습니다. 그렇지 않은 경우 메소드를 실행하고 반환 값을 캐시에 넣으면 @cacheput는 메소드를 먼저 실행 한 다음 실행 결과를 캐시에 작성합니다. @cacheput를 사용하는 방법은 확실히 실행됩니다
전체 샘플 코드는 https://github.com/ldwqh0/cache-test에 있습니다
요약
위는 편집기가 소개 한 스프링 부팅에서 캐시 캐시를 사용하는 방법입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!