Spring에서 JPA를 사용하는 경우 2차 캐싱을 수행할 때 보통 caching provider(redis 같은..)와 jpa(hibernate)간 설정을 하기위해 RegionFactory
를 사용한다. 그런데 이렇게 사용하는 경우 JPA 2차 캐시를 위해 내부적으로 caching provider가 설정되어 있는데 bean으로 등록되는 것은 아니기 때문에 JPA 2차 캐시 이외의 용도로 caching provider를 활용하기 위해 별도의 bean을 생성해야 할 수 있다(RedissonClient
같은 거)
하지만 하나의 어플리케이션에서 동일 caching provider를 활용하기 위해 추가적인 client object를 생성하는 것은 리소스의 낭비나 예상 외 문제를 야기할 수 있다.
보통 caching provider의 RegionFactory
를 살펴보면 내부에 client object가 존재한다. 따라서 RegionFactory
를 가져와서 내부의 client object를 bean으로 등록해줄 수 있다면 이를 해결해 줄 수 있을 것이다.
그렇다면 RegionFactory
는 어디에 위치할까? 링크를 살펴보면 2차 캐싱을 제어하는 경우 EntityManagerFactory
나 SessionFactory
에 바인딩 되기 때문에 무언가 하려면 해당 인터페이스를 통해야 한다고 한다.
spring-data-jpa
를 사용했다면 EntityManagerFactory
로 부터 가져올 수 있다.
@Component
class CacheInstanceHolder(
entityManagerFactory: EntityManagerFactory
) {
final val cacheProviderInstance: YourCacheClient =
when(val regionFactory = (entityManagerFactory.cache as CacheImplementor).regionFactory) {
is YourCacheRegionFactory -> regionFactory.yourCacheClient
else -> TODO("unknown region factory")
}
}
EntityManagerFactory
는 JPA의 스펙이기 때문에 hibernate의 스펙인 RegionFactory
를 가져오려면 구현체인 CacheImplementor
로 형변환을 해주고 RegionFactory
를 가져올 수 있다.
가져오고 나면 자신이 사용하는 RegionFactory
의 구현체로 변환하고 그로부터 원하는 리소스를 가져오면 된다.
RedissonRegionFactory의 경우 RedissonClient가 private필드고 getter가 없기 때문에 RedissonClient의 객체를 사용하고 싶다면 RedissonRegionFactory를 상속해서 getter를 만들어주자.