33 Caching by ks

Spring Framework는 애플리케이션에 캐싱을 투명하게 추가 할 수 있도록 지원합니다. 코어에서, 추상화는 메소드에 캐싱을 적용하여 캐시에서 사용 가능한 정보를 기반으로 실행 횟수를 줄입니다. 캐싱 로직은 호출자에 대한 간섭없이 투명하게 적용됩니다. Spring Boot는 캐싱 지원이 @EnableCaching 주석을 통해 활성화되어있는 한 캐시 인프라를 자동으로 구성합니다.

자세한 내용은 Spring Framework 레퍼런스의 관련 섹션을 확인하십시오.

간단히 말해서, 서비스 작동에 캐싱을 추가하는 것은 다음 예제와 같이 해당 주석을 메소드에 추가하는 것만 큼 쉽습니다.

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component
public class MathService {

	@Cacheable("piDecimals")
	public int computePiDecimal(int i) {
		// ...
	}

}

이 예제는 비용이 많이 드는 작업에 캐싱을 사용하는 방법을 보여줍니다. computePiDecimal을 호출하기 전에 추상화는 piDecimals 캐시에서 i 인수와 일치하는 항목을 찾습니다. 항목이 발견되면 캐시의 내용은 즉시 호출자에게 리턴되고 메소드는 호출되지 않습니다. 그렇지 않으면 메서드가 호출되고 값을 반환하기 전에 캐시가 업데이트됩니다.

주의

또한 표준 JSR-107 (JCache) 주석 (예 : @CacheResult)을 투명하게 사용할 수 있습니다. 그러나 스프링 캐시와 JCache 주석을 섞어서 사용하지 않는 것이 좋습니다.

특정 캐시 라이브러리를 추가하지 않으면 스프링 부트는 메모리에서 동시 맵을 사용하는 단순한 제공자를 자동으로 구성합니다. 캐시가 필요한 경우 (위 예에서 piDecimals와 같이),이 제공자가 대신 캐시를 만듭니다. 간단한 프로 바이더는 프로덕션 사용에는 권장되지 않지만, 시작하고 기능을 이해하는 것이 좋습니다. 사용할 캐시 공급자에 대해 생각해 봤으면 해당 설명서를 읽고 응용 프로그램에서 사용하는 캐시를 구성하는 방법을 알아보십시오. 거의 모든 공급자는 응용 프로그램에서 사용하는 모든 캐시를 명시 적으로 구성해야합니다. 일부는 spring.cache.cache-names 등록 정보로 정의 된 기본 캐시를 사용자 정의하는 방법을 제공합니다.

캐시에서 데이터를 투명하게 업데이트하거나 제거 할 수도 있습니다.

33.1 지원하는 cache provider

캐시 추상화는 실제 저장소를 제공하지 않으며 org.springframework.cache.Cache 및 org.springframework.cache.CacheManager 인터페이스에 의해 구체화 된 추상화에 의존합니다.

CacheManager 유형의 bean이나 cacheResolver라는 CacheResolver (CachingConfigurer 참조)를 정의하지 않은 경우, Spring Boot는 다음 순서로 제공자를 검색하려고 시도합니다.

  1. JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)

spring.cache.type 속성을 설정하여 특정 캐시 공급자를 강제로 수행 할 수도 있습니다. 특정 환경 (예 : 테스트)에서 캐싱을 모두 비활성화해야하는 경우이 속성을 사용합니다.

spring-boot-starter-cache "Starter"를 사용하여 기본 캐싱 종속성을 빠르게 추가 할 수 있습니다. 스타터는 spring-context-support에서 가져온다. 종속성을 수동으로 추가하는 경우 JCache, EhCache 2.x 또는 Guava 지원을 사용하려면 스프링 컨텍스트 지원을 포함시켜야합니다.

CacheManager가 Spring Boot에 의해 자동 구성되면, CacheManagerCustomizer 인터페이스를 구현하는 bean을 노출시킴으로써 완전히 초기화되기 전에 구성을 더 조정할 수 있습니다. 다음 예제는 NULL 값을 기본 맵으로 전달해야한다는 플래그를 설정합니다.

@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
	return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
		@Override
		public void customize(ConcurrentMapCacheManager cacheManager) {
			cacheManager.setAllowNullValues(false);
		}
	};
}

앞의 예제에서는 자동으로 구성된 ConcurrentMapCacheManager가 필요합니다. 그렇지 않은 경우 (자체 구성을 제공했거나 다른 캐시 공급자가 자동 ​​구성되어있는 경우) 사용자 지정 프로그램이 전혀 호출되지 않습니다. 원하는 수만큼 커스터마이징 할 수 있으며 @Order 또는 Ordered를 사용하여 주문할 수도 있습니다.

33.1.1 제네릭

컨텍스트가 적어도 하나의 org.springframework.cache.Cache 빈을 정의하면 일반 캐싱이 사용됩니다. 해당 유형의 모든 bean을 랩핑하는 CacheManager가 작성됩니다.

33.1.2 JCache (JSR-107)

JCache는 classpath에있는 javax.cache.spi.CachingProvider를 통해 부트 스트랩됩니다 (즉, 클래스 경로에 JSR-107 호환 캐시 라이브러리가 있음). JCacheCacheManager는 spring-boot-starter-cache "Starter"에 의해 제공됩니. 다양한 호환 라이브러리를 사용할 수 있으며 Spring Boot는 Ehcache 3, Hazelcast 및 Infinispan에 대한 종속성 관리를 제공합니다. 다른 호환 라이브러리도 추가 할 수 있습니다.

둘 이상의 제공자가 존재할 수 있으며,이 경우 제공자를 명시 적으로 지정해야합니다. JSR-107 표준이 구성 파일의 위치를 ​​정의하는 표준화 된 방법을 시행하지 않더라도 스프링 부트는 구현 세부 사항이있는 캐시 설정을 수용하기 위해 최선을 다합니다 (다음 예 참조).

   # Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml

캐시 라이브러리가 네이티브 구현과 JSR-107 지원을 모두 제공 할 때 스프링 부트는 JSR-107 지원을 선호하므로 다른 JSR-107 구현으로 전환해도 동일한 기능을 사용할 수있다.

Spring Boot는 Hazelcast에 대한 일반적인 지원을합니다. Spring.cache.jcache.config 속성이 지정되어 있지 않은 한 하나의 HazelcastInstance가 사용 가능하면 CacheManager에 대해서도 자동으로 재사용됩니다.

기본 javax.cache.cacheManager를 사용자 정의하는 두 가지 방법이 있습니다.

캐시는 spring.cache.cache-names 속성을 설정하여 시작할 때 생성 될 수 있습니다.

  1. 커스텀 javax.cache.configuration.Configuration 빈이 정의되어 있다면 커스터마이징하는데 사용됩니다

  2. org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer 빈은 전체 사용자 정의를 위해 CacheManager 참조와 함께 호출된다.

표준 javax.cache.CacheManager bean이 정의되면 추상화가 예상하는 org.springframework.cache.CacheManager 구현에 자동으로 랩핑됩니다. 더 이상 사용자 정의가 적용되지 않습니다.

33.1.3 EhCache 2.x

EhCache 2.x는 ehcache.xml 파일이 클래스 경로의 루트에서 발견 될 때 사용됩니다. EhCache 2.x가 발견되면 spring-boot-starter-cache "Starter"가 제공하는 EhCacheCacheManager를 사용하여 캐시 관리자를 부트 스트랩합니다. 다음 예제와 같이 대체 구성 파일을 제공 할 수도 있습니다.

spring.cache.ehcache.config=classpath:config/another-config.xml

33.1.4 Hazelcast

Spring Boot는 Hazelcast에 대한 일반적인 지원을합니다. HazelcastInstance가 자동으로 구성된 경우 자동으로 CacheManager에 래핑됩니다.

33.1.5 Infinispan

Infinispan에는 기본 구성 파일 위치가 없으므로 명시 적으로 지정해야합니다. 그렇지 않으면 기본 부트 스트랩이 사용됩니다.

spring.cache.infinispan.config=infinispan.xmlspring.cache.infinispan.config=infinispan.xml

캐시는 spring.cache.cache-names 속성을 설정하여 시작할 때 생성 될 수 있습니다. 커스텀 ConfigurationBuilder 빈이 정의되어 있으면 캐시를 커스터마이징하는 데 사용됩니다.

Spring Boot에서 Infinispan의 지원은 임베디드 모드로 제한되어 있으며 매우 기본입니다. 더 많은 옵션을 원한다면 공식 Infinispan Spring Boot 스타터를 사용해야합니다. 자세한 내용은 Infinispan의 설명서를 참조하십시오.

33.1.6 Couchbase

Couchbase Java 클라이언트와 couchbase-spring-cache 구현을 사용할 수 있고 Couchbase가 구성되어 있으면 CouchbaseCacheManager가 자동으로 구성됩니다. spring.cache.cache-names 속성을 설정하여 시작할 때 추가 캐시를 생성 할 수도 있습니다. 이러한 캐시는 자동 구성된 Bucket에서 작동합니다. 또한 사용자 정의 프로그램을 사용하여 다른 버킷에 추가 캐시를 작성할 수 있습니다. "기본"버킷에는 2 개의 캐시 (cache1 및 cache2)가 필요하고 "다른"버킷에는 2 초의 사용자 정의 시간이있는 캐시 (cache3)가 필요합니다. 다음과 같이 구성을 통해 처음 두 개의 캐시를 만들 수 있습니다.

Couchbase는 json 기반의 noSQL DB 인데, 버킷은 RDBS의 데이터베이스같은 공간이다. json 도큐멘트들은 다 이곳에 저장된다.

spring.cache.cache-names=cache1,cache2

그런 다음 @Configuration 클래스를 정의하여 다음과 같이 여분의 버킷과 cache3 캐시를 구성 할 수 있습니다.

@Configuration
public class CouchbaseCacheConfiguration {

	private final Cluster cluster;

	public CouchbaseCacheConfiguration(Cluster cluster) {
		this.cluster = cluster;
	}

	@Bean
	public Bucket anotherBucket() {
		return this.cluster.openBucket("another", "secret");
	}

	@Bean
	public CacheManagerCustomizer<CouchbaseCacheManager> cacheManagerCustomizer() {
		return c -> {
			c.prepareCache("cache3", CacheBuilder.newInstance(anotherBucket())
					.withExpiration(2));
		};
	}

}

이 샘플 구성은 자동 구성을 통해 만들어진 클러스터를 다시 사용합니다.

33.1.7 Redis

Redis가 사용 가능하고 구성되어 있으면 RedisCacheManager가 자동으로 구성됩니다. spring.cache.credit. * 속성을 사용하여 spring.cache.cache-names 속성과 cache default 속성을 설정하여 시작할 때 추가 캐시를 만들 수 있습니다. 예를 들어, 다음 구성은 10 분의 지속 시간으로 cache1 및 cache2 캐시를 작성합니다.

spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=600000

기본적으로 키 접두사가 추가되어 두 개의 별도 캐시가 동일한 키를 사용하는 경우 Redis는 중복 키가 없으며 잘못된 값을 반환 할 수 없도록합니다. 고유 한 RedisCacheManager를 생성하는 경우이 설정을 활성화 된 상태로 유지하는 것이 좋습니다.

RedisCacheConfiguration @ Bean을 추가하여 구성을 완전히 제어 할 수 있습니다. 이것은 직렬화 전략을 사용자 정의하려는 경우에 유용 할 수 있습니다.

33.1.8 Caffein

카페인은 구아바에 대한 지원을 대신하는 자바 8 캐시의 재 작성입니다. Caffeine이 있으면 CaffeineCacheManager (spring-boot-starter-cache "Starter"가 제공)가 자동으로 구성됩니다. 캐시는 spring.cache.cache-names 속성을 설정하여 시작할 때 만들 수 있으며 다음 순서 중 하나로 사용자 정의 할 수 있습니다 (표시된 순서대로).

  1. spring.cache.caffeine.spec에 정의 된 캐시 사양

  2. com.github.benmanes.caffeine.cache.CaffeineSpec bean이 정의되었습니다.

  3. com.github.benmanes.caffeine.cache.Caffeine 빈이 정의되었습니다.

예를 들어, 다음 구성은 최대 크기가 500이고 작동 시간이 10 분인 cache1 및 cache2 캐시를 작성합니다.

spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

com.github.benmanes.caffeine.cache.CacheLoader bean이 정의되면 CaffeineCacheManager에 자동으로 연관됩니다. CacheLoader는 캐시 관리자가 관리하는 모든 캐시와 연관되기 때문에 CacheLoader 로 정의되어야합니다. 자동 구성은 다른 제네릭 형식을 무시합니다.

33.1.9 Simple

다른 프로 바이더가 발견되지 않는 경우, ConcurrentHashMap를 캐쉬 · 스토어로서 사용하는 간단한 구현이 설정됩니다. 응용 프로그램에 캐싱 라이브러리가없는 경우 이것이 기본값입니다. 기본적으로 캐시는 필요에 따라 만들어 지지만 cache-names 속성을 설정하여 사용 가능한 캐시 목록을 제한 할 수 있습니다. 예를 들어, cache1 및 cache2 캐시 만 원한다면 다음과 같이 cache-names 등록 정보를 설정하십시오.

spring.cache.cache-names=cache1,cache2

그렇게하고 응용 프로그램이 나열되지 않은 캐시를 사용하면 캐시가 필요할 때 런타임에 실패하지만 시작시 실패합니다. 이는 선언되지 않은 캐시를 사용하는 경우 "실제"캐시 공급자가 작동하는 방식과 유사합니다.

33.1.10 None

구성에 @EnableCaching이 있으면 적절한 캐시 구성이 필요합니다. 특정 환경에서 캐싱을 모두 비활성화해야하는 경우 다음 예와 같이 캐시 유형을 없음으로 설정하여 아무 작업도 수행하지 마십시오.

spring.cache.type=none

Last updated