https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-jsr-107
Integration
The Spring Framework provides abstractions for the asynchronous execution and scheduling of tasks with the TaskExecutor and TaskScheduler interfaces, respectively. Spring also features implementations of those interfaces that support thread pools or delega
docs.spring.io
틀린 해석이 있다면 알려주세요 🐱
6.3. JCache (JSR-107) Annotations ~ 6.7. How can I Set the TTL/TTI/Eviction policy/XXX feature?
6.3. JCache (JSR-107) Annotations
Spring 4.1 부터는
JCache 표준(JSR-107) 주석과 @CacheDefaults, @CacheKey 및 @CacheValue 를 동시에 지원하고 있다.
이전 버전과 같게 지원해준다는 뜻이니 슉 빠르게 보고 넘기겠음
6.3.1. Feature Summary
Spring vs. JSR-107 caching annotationsSpringJSR-107Remark
@Cacheable | @CacheResult | Fairly similar. @CacheResult can cache specific exceptions and force the execution of the method regardless of the content of the cache. |
@CachePut | @CachePut | While Spring updates the cache with the result of the method invocation, JCache requires that it be passed it as an argument that is annotated with @CacheValue. Due to this difference, JCache allows updating the cache before or after the actual method invocation. |
@CacheEvict | @CacheRemove | Fairly similar. @CacheRemove supports conditional eviction when the method invocation results in an exception. |
@CacheEvict(allEntries=true) | @CacheRemoveAll | See @CacheRemove. |
@CacheConfig | @CacheDefaults | Lets you configure the same concepts, in a similar fashion. |
JCache 는 단일 캐시만 지원한다는 점을 제외하고
javax.cache.annotation.CacheResolver 인터페이스와 동일한 개념임
CacheResolber는 기본적으로 간단하게 선언된 이름을 기반으로 사용할 캐시를 검색한다
주석에 캐시 이름이 지정되지 않아면 알아서 기본값이 자동 생성 된다
CacheResolverFactory 를 이용하여 검색된다.
팩토리를 사용자 지정할 수 있다
@CacheResult(cacheNames="books", cacheResolverFactory=MyCacheResolverFactory.class)
public Book findBook(ISBN isbn)
** Spring은 참조된 모든 클래스에 대해 주어진 type의 bean을 찾으려고 한다
둘 이상의 일치 항목이 있다면 새 인스턴스가 생성되고, 종속성 주입과 같은 bean life cycle callback에 사용할 수 있다
Keys are generated by a javax.cache.annotation.CacheKeyGenerator that serves the same purpose as Spring’s KeyGenerator. By default, all method arguments are taken into account, unless at least one parameter is annotated with @CacheKey. This is similar to Spring’s custom key generation declaration. For instance, the following are identical operations, one using Spring’s abstraction and the other using JCache:
@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@CacheResult(cacheName="books")
public Book findBook(@CacheKey ISBN isbn, boolean checkWarehouse, boolean includeUsed)
You can also specify the CacheKeyResolver on the operation, similar to how you can specify the CacheResolverFactory.
JCache can manage exceptions thrown by annotated methods. This can prevent an update of the cache, but it can also cache the exception as an indicator of the failure instead of calling the method again. Assume that InvalidIsbnNotFoundException is thrown if the structure of the ISBN is invalid. This is a permanent failure (no book could ever be retrieved with such a parameter). The following caches the exception so that further calls with the same, invalid, ISBN throw the cached exception directly instead of invoking the method again:
@CacheResult(cacheName="books", exceptionCacheName="failures"
cachedExceptions = InvalidIsbnNotFoundException.class)
public Book findBook(ISBN isbn)
6.3.2. Enabling JSR-107 Support
Both @EnableCaching and the cache:annotation-driven XML element automatically enable the JCache support if both the JSR-107 API and the spring-context-support module are present in the classpath.
6.4. Declarative XML-based Caching
xml로 캐싱을 선언적으로 사용할 수 있다
이것도.. 내가 쓸일이 없기에.. 슉 보고 넘긴다
<!-- the service we want to make cacheable -->
<bean id="bookService" class="x.y.service.DefaultBookService"/>
<!-- cache definitions -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
<cache:caching cache="books">
<cache:cacheable method="findBook" key="#isbn"/>
<cache:cache-evict method="loadBooks" all-entries="true"/>
</cache:caching>
</cache:advice>
<!-- apply the cacheable behavior to all BookService interfaces -->
<aop:config>
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
</aop:config>
<!-- cache manager definition omitted -->
In the preceding configuration, the bookService is made cacheable. The caching semantics to apply are encapsulated in the cache:advice definition, which causes the findBooks method to be used for putting data into the cache and the loadBooks method for evicting data. Both definitions work against the books cache.
The aop:config definition applies the cache advice to the appropriate points in the program by using the AspectJ pointcut expression (more information is available in Aspect Oriented Programming with Spring). In the preceding example, all methods from the BookService are considered and the cache advice is applied to them.
The declarative XML caching supports all of the annotation-based model, so moving between the two should be fairly easy. Furthermore, both can be used inside the same application. The XML-based approach does not touch the target code. However, it is inherently more verbose. When dealing with classes that have overloaded methods that are targeted for caching, identifying the proper methods does take an extra effort, since the method argument is not a good discriminator. In these cases, you can use the AspectJ pointcut to cherry pick the target methods and apply the appropriate caching functionality. However, through XML, it is easier to apply package or group or interface-wide caching (again, due to the AspectJ pointcut) and to create template-like definitions (as we did in the preceding example by defining the target cache through the cache:definitions cache attribute).
6.5. Configuring the Cache Storage
Cache Abstraction은 여러 storage 통합 옵션을 제공한다. 적절한 CacheManager(an entity that controls and manages Cache instances and that can be used to retrieve these for storage) 를 선언해서 사용해야한다
6.5.1. JDK ConcurrentMap-based Cache
The JDK-based Cache implementation resides under org.springframework.cache.concurrent package. It lets you use ConcurrentHashMap as a backing Cache store. The following example shows how to configure two caches:
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
</set>
</property>
</bean>
The preceding snippet uses the SimpleCacheManager to create a CacheManager for the two nested ConcurrentMapCache instances named default and books. Note that the names are configured directly for each cache.
As the cache is created by the application, it is bound to its lifecycle, making it suitable for basic use cases, tests, or simple applications. The cache scales well and is very fast, but it does not provide any management, persistence capabilities, or eviction contracts.
6.5.2. Ehcache-based Cache
Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. See JSR-107 Cache for details.
6.5.3. Caffeine Cache
// 그래ㅠㅠ 이게 공부하고 싶었어
Caffeine is a Java 8 rewrite of Guava’s cache, and its implementation is located in the org.springframework.cache.caffeine package and provides access to several features of Caffeine.
xml 사용방법이다
<bean id="cacheManager"
class="org.springframework.cache.caffeine.CaffeineCacheManager"/>
사용자 명시로 제공할 수도 있다
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
<property name="cacheNames">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
The Caffeine CacheManager also supports custom Caffeine and CacheLoader. See the Caffeine documentation for more information about those.
Home
A high performance caching library for Java. Contribute to ben-manes/caffeine development by creating an account on GitHub.
github.com
6.5.4. GemFire-based Cache
GemFire is a memory-oriented, disk-backed, elastically scalable, continuously available, active (with built-in pattern-based subscription notifications), globally replicated database and provides fully-featured edge caching. For further information on how to use GemFire as a CacheManager (and more), see the Spring Data GemFire reference documentation.
6.5.5. JSR-107 Cache
Spring’s caching abstraction can also use JSR-107-compliant caches. The JCache implementation is located in the org.springframework.cache.jcache package.
Again, to use it, you need to declare the appropriate CacheManager. The following example shows how to do so:
<bean id="cacheManager"
class="org.springframework.cache.jcache.JCacheCacheManager"
p:cache-manager-ref="jCacheManager"/>
<!-- JSR-107 cache manager setup -->
<bean id="jCacheManager" .../>
6.5.6. Dealing with Caches without a Backing Store
Sometimes, when switching environments or doing testing, you might have cache declarations without having an actual backing cache configured. As this is an invalid configuration, an exception is thrown at runtime, since the caching infrastructure is unable to find a suitable store. In situations like this, rather than removing the cache declarations (which can prove tedious), you can wire in a simple dummy cache that performs no caching — that is, it forces the cached methods to be invoked every time. The following example shows how to do so:
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="jdkCache"/>
<ref bean="gemfireCache"/>
</list>
</property>
<property name="fallbackToNoOpCache" value="true"/>
</bean>
The CompositeCacheManager in the preceding chains multiple CacheManager instances and, through the fallbackToNoOpCache flag, adds a no-op cache for all the definitions not handled by the configured cache managers. That is, every cache definition not found in either jdkCache or gemfireCache (configured earlier in the example) is handled by the no-op cache, which does not store any information, causing the target method to be invoked every time.
6.6. Plugging-in Different Back-end Caches
Clearly, there are plenty of caching products out there that you can use as a backing store. For those that do not support JSR-107 you need to provide a CacheManager and a Cache implementation. This may sound harder than it is, since, in practice, the classes tend to be simple adapters that map the caching abstraction framework on top of the storage API, as the Caffeine classes do. Most CacheManager classes can use the classes in the org.springframework.cache.support package (such as AbstractCacheManager which takes care of the boiler-plate code, leaving only the actual mapping to be completed).
Caffeine 클래스 처럼 storage API 위에 캐시 추상화 프레임워크를 매핑하는 adaptor 같은 느낌이다
6.7. How can I Set the TTL/TTI/Eviction policy/XXX feature?
Directly through your cache provider. The cache abstraction is an abstraction, not a cache implementation. The solution you use might support various data policies and different topologies that other solutions do not support (for example, the JDK ConcurrentHashMap — exposing that in the cache abstraction would be useless because there would no backing support). Such functionality should be controlled directly through the backing cache (when configuring it) or through its native API.
캐시 추상화는 구현이 아니라 추상화이므로, 다양한 data 정책과 토폴로지를 지원할 수 있다. 대신 백업 캐시 또는 기본 API를 통해 직접 제어해야한다
'Web > spring' 카테고리의 다른 글
[Spring guide] Caching Data with Spring (0) | 2023.02.28 |
---|---|
[Spring Boot IO] 1. Caching (0) | 2023.02.28 |
[Spring Framework integration] 6.Cache Abstraction (1) (0) | 2023.02.27 |
[Spring REST] Setting up Your Tests (0) | 2023.02.26 |
[Spring data] JPA repositories - Projection (0) | 2023.02.26 |